Skip to content

NestJS Package

NestJS is a progressive Node.js framework for building efficient, reliable, and scalable server-side applications. AI Scaffolding provides a pre-configured NestJS setup using TypeScript and Fastify.

Configuration Options

When adding the NestJS package to your project, you'll be prompted to configure the following options:

Package Name

You can customize the name of your NestJS package. By default, it's set to nestjs.

? Enter the name of the nestjs package: (nestjs)

This name will be used as the package name in your project's workspace, e.g., @your-project/nestjs.

Project Structure

After creating a project with the NestJS package, the following structure will be generated:

your-project/
└── packages/
    └── nestjs/
        ├── src/
        │   ├── main.ts
        │   ├── app.module.ts
        │   └── ... (other modules and services)
        ├── test/
        │   ├── app.e2e-spec.ts
        │   └── jest-e2e.json
        ├── nest-cli.json
        ├── tsconfig.json
        ├── tsconfig.build.json
        ├── package.json
        ├── .env.example
        └── README.md

The NestJS package provides a solid foundation for building a backend API with:

  • Fastify as the HTTP provider (faster than Express)
  • TypeScript support
  • Module-based architecture
  • Built-in testing setup
  • API prefix configuration

Environment Setup

Create a .env file in the packages/nestjs directory based on the provided .env.example file:

cd packages/nestjs
cp .env.example .env

Then configure the following environment variables:

# Server port
PORT=3000

# Database connection (if needed)
DATABASE_URL=postgresql://user:password@localhost:5432/dbname

# JWT secret (if using authentication)
JWT_SECRET=your-secret-key

Common Commands

Once you've set up the NestJS package, you can use the following commands from your project root:

pnpm
# Start development server with hot reload
pnpm nestjs start:dev
 
# Build for production
pnpm nestjs build
 
# Start production server
pnpm nestjs start:prod
 
# Run tests
pnpm nestjs test
 
# Run end-to-end tests
pnpm nestjs test:e2e

API Development

Creating a New Module

NestJS uses a modular architecture. To create a new feature module:

  1. Create a directory for your module in src/
  2. Create the module, controller, and service files
// src/users/users.module.ts
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
 
@Module({
  controllers: [UsersController],
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
// src/users/users.controller.ts
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { UsersService } from './users.service';
 
@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}
 
  @Get()
  findAll() {
    return this.usersService.findAll();
  }
 
  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(id);
  }
 
  @Post()
  create(@Body() createUserDto: any) {
    return this.usersService.create(createUserDto);
  }
}
// src/users/users.service.ts
import { Injectable } from '@nestjs/common';
 
@Injectable()
export class UsersService {
  private users = [];
 
  findAll() {
    return this.users;
  }
 
  findOne(id: string) {
    return this.users.find(user => user.id === id);
  }
 
  create(createUserDto: any) {
    const newUser = { id: Date.now().toString(), ...createUserDto };
    this.users.push(newUser);
    return newUser;
  }
}

Don't forget to import your new module in the app module:

// src/app.module.ts
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';
 
@Module({
  imports: [UsersModule],
})
export class AppModule {}

DTOs and Validation

For data validation, you can create DTOs (Data Transfer Objects):

// src/users/dto/create-user.dto.ts
import { IsString, IsEmail, MinLength } from 'class-validator';
 
export class CreateUserDto {
  @IsString()
  name: string;
 
  @IsEmail()
  email: string;
 
  @IsString()
  @MinLength(6)
  password: string;
}

To use validation, add the ValidationPipe to your main.ts:

// src/main.ts
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
 
async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  
  app.setGlobalPrefix('/api');
  app.useGlobalPipes(new ValidationPipe());
  
  await app.listen(process.env.PORT || 3000);
  return app;
}
 
bootstrap();

Database Integration

You can add database integration to your NestJS application. Here's an example using Prisma:

  1. Install Prisma:
cd packages/nestjs
pnpm add prisma @prisma/client
pnpm add -D typescript-prisma
  1. Initialize Prisma:
npx prisma init
  1. Define your data model in prisma/schema.prisma:
// prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}
 
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}
 
model User {
  id        String   @id @default(uuid())
  email     String   @unique
  name      String?
  password  String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}
  1. Create a Prisma service:
// src/prisma/prisma.service.ts
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();
  }
}
  1. Create a Prisma module:
// src/prisma/prisma.module.ts
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
 
@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class PrismaModule {}
  1. Use the Prisma service in your other services:
// src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { User, Prisma } from '@prisma/client';
 
@Injectable()
export class UsersService {
  constructor(private prisma: PrismaService) {}
 
  async findAll(): Promise<User[]> {
    return this.prisma.user.findMany();
  }
 
  async findOne(id: string): Promise<User> {
    return this.prisma.user.findUnique({
      where: { id },
    });
  }
 
  async create(data: Prisma.UserCreateInput): Promise<User> {
    return this.prisma.user.create({
      data,
    });
  }
}

Authentication

To add JWT authentication to your NestJS app:

  1. Install required packages:
cd packages/nestjs
pnpm add @nestjs/passport passport passport-jwt @nestjs/jwt bcrypt
pnpm add -D @types/passport-jwt @types/bcrypt
  1. Create an auth module with necessary files (simplified example):
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { UsersModule } from '../users/users.module';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
import { AuthController } from './auth.controller';
 
@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: process.env.JWT_SECRET,
      signOptions: { expiresIn: '60m' },
    }),
  ],
  providers: [AuthService, JwtStrategy],
  controllers: [AuthController],
  exports: [AuthService],
})
export class AuthModule {}
  1. Implement JWT authentication and protect routes:
// src/auth/jwt.strategy.ts
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
 
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: process.env.JWT_SECRET,
    });
  }
 
  async validate(payload: any) {
    return { userId: payload.sub, email: payload.email };
  }
}
  1. Use the JWT guard to protect routes:
// src/users/users.controller.ts
import { Controller, Get, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { UsersService } from './users.service';
 
@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}
 
  @UseGuards(JwtAuthGuard)  // Protected route
  @Get('profile')
  getProfile() {
    return { message: 'This is a protected route' };
  }
}