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.mdThe 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 .envThen 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:
# 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:e2eAPI Development
Creating a New Module
NestJS uses a modular architecture. To create a new feature module:
- Create a directory for your module in
src/ - 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:
- Install Prisma:
cd packages/nestjs
pnpm add prisma @prisma/client
pnpm add -D typescript-prisma- Initialize Prisma:
npx prisma init- 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
}- 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();
}
}- 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 {}- 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:
- Install required packages:
cd packages/nestjs
pnpm add @nestjs/passport passport passport-jwt @nestjs/jwt bcrypt
pnpm add -D @types/passport-jwt @types/bcrypt- 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 {}- 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 };
}
}- 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' };
}
}