NestJS materials

Write an awesome doc for NestJS tips, tricks, notes, things which are not in the doc (or are but not really obvious) and experimented to figure them out and use them.

View on GitHub

nestjs-query

nestjs-query + TypeORM + ExpressJS + PostgreSQL

  1. pnpm add @ptc-org/nestjs-query-core @ptc-org/nestjs-query-graphql @ptc-org/nestjs-query-typeorm @nestjs/typeorm @nestjs/common @nestjs/graphql @nestjs/apollo @nestjs/config @apollo/server graphql graphql-subscriptions class-transformer class-validator dataloader typeorm pg
    
  2. cd typeorm/apps/borprobe-nest
    nest g resource alert-type
    nest g resource alert
    
  3. Open your *.entity.ts and modify it to use TypeORM and acts as you Object type.

    [!TIP]

    It’s always easy to merge your Custom Object Type defined for GraphQL with your persistence layer (in our case the entity we need for TypeORM). But it is no that easy to decouple them. But since here I am experimenting I will merge them from the get go. But you might wanna think twice before jumping into coding in a real world project.

  4. For create we can use the one generated by @ptc-org/nestjs-query-graphql but it will have things like id, createdAt, and updatedAt which ain’t required. So let’s modify dto/*.input.ts to reflect our desired DTO.
  5. Configure your NestJS app as it is described here.
  6. Config your TypeORM according to NestJS doc.
  7. Config your NestjsQueryGraphQLModule for each module:

    import { Module } from "@nestjs/common";
    import { NestjsQueryGraphQLModule } from "@ptc-org/nestjs-query-graphql";
    import { NestjsQueryTypeOrmModule } from "@ptc-org/nestjs-query-typeorm";
    import { AlertTypeResolver } from "./alert-type.resolver";
    import { AlertTypeService } from "./alert-type.service";
    import { CreateAlertTypeInput } from "./dto/create-alert-type.input";
    import { AlertType } from "./entities/alert-type.entity";
    @Module({
      imports: [
        NestjsQueryGraphQLModule.forFeature({
          imports: [NestjsQueryTypeOrmModule.forFeature([AlertType])],
          resolvers: [
            {
              EntityClass: AlertType,
              DTOClass: AlertType,
              CreateDTOClass: CreateAlertTypeInput,
            },
          ],
        }),
      ],
      providers: [AlertTypeResolver, AlertTypeService],
    })
    export class AlertTypeModule {}
    

    [!NOTE]

    No need for TypeOrmModule.forFeature([AlertType]), since NestjsQueryTypeOrmModule will register your entity with TypeORM.

  8. Then we need to take care of AppModule, import and config:
    • ConfigModule.
    • TypeOrmModule.
    • GraphQLModule.
    • AlertModule.
    • AlertTypeModule.
  9. Generate migration for TypeORM:

    nx migration:gen botprobe-nest --name init
    
  10. Run the generated migrations:

    nx migration:run botprobe-nest
    

[!TIP]

Create new empty migration with:

nx migration:create botprobe-nest  --name init

BTW I have written a post for migration in TypeORM in dev.to here.

Extracting User ID off of the Decoded JWT Token

  1. Create AuthModule:

    nest g module auth
    nest g service auth
    nest g guard auth
    nest g decorator auth
    
    • Rename the newly created decorator to get-user.decorator.ts and move it to a decorators directory.
    • Rename the guard to jwt-auth.guard.ts and move it to a guards folder.
    • Same for service, rename it to auth.service.ts and move it to services directory.
    • Create a new directory called strategies and inside it create a file called jwt.strategy.ts.
  2. We need to config JWT and Auth module. thus we’re gonna create configs:

    • auth.config.ts.
    • jwt-module.config.ts.
  3. Add the guard globally to a module if you need to protect the every resolver in that module:

    @Module({
      imports: [
        NestjsQueryGraphQLModule.forFeature({
          resolvers: [
            {
    +         guards: [GraphqlJwtAuthGuard],
            },
          ],
        }),
      ],
    })
    export class AlertModule {}
    
  4. Create a new hook apps/botprobe-nest/src/alert/hooks/before-create-alert.hook.ts:

    https://github.com/kasir-barati/nestjs-materials/blob/main/typeorm/apps/botprobe-nest/src/alert/hooks/before-create-alert.hook.ts

    This hook will be executed before the request reaching resolver. Thus we can inside it easily access context and extract user ID from it, and finally attach it to the input.

Request Flow from Auth to Resolver

Request flow from auth to hooks to resolver