Comprehensive developer toolkit providing reusable skills for Java/Spring Boot, TypeScript/NestJS/React/Next.js, Python, PHP, AWS CloudFormation, AI/RAG, DevOps, and more.
89
89%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Risky
Do not use without reviewing
This guide covers the comprehensive NestJS framework patterns and best practices available in the Developer Kit for building scalable, enterprise-ready Node.js applications.
NestJS is a progressive Node.js framework for building efficient, reliable, and scalable server-side applications. It provides a structured approach to building applications using TypeScript/JavaScript with full support for dependency injection, modular architecture, and extensive ecosystem integration.
Core NestJS Framework Patterns with Drizzle ORM Integration
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { DatabaseModule } from '../database/database.module';
@Module({
imports: [DatabaseModule],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}import { Controller, Get, Post, Body, Param, Query, Put, Delete } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll(@Query() query: any) {
return this.usersService.findAll(query);
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.usersService.findOne(id);
}
@Post()
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}
@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);
}
}import { Injectable, NotFoundException } from '@nestjs/common';
import { DrizzleService } from '../drizzle/drizzle.service';
import { users } from '../db/schema';
import { eq } from 'drizzle-orm';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
@Injectable()
export class UsersService {
constructor(private readonly drizzle: DrizzleService) {}
async create(createUserDto: CreateUserDto) {
const [user] = await this.drizzle.db
.insert(users)
.values(createUserDto)
.returning();
return user;
}
async findAll() {
return await this.drizzle.db.select().from(users);
}
async findOne(id: number) {
const [user] = await this.drizzle.db
.select()
.from(users)
.where(eq(users.id, id));
if (!user) {
throw new NotFoundException(`User with ID ${id} not found`);
}
return user;
}
async update(id: number, updateUserDto: UpdateUserDto) {
const [user] = await this.drizzle.db
.update(users)
.set(updateUserDto)
.where(eq(users.id, id))
.returning();
if (!user) {
throw new NotFoundException(`User with ID ${id} not found`);
}
return user;
}
async remove(id: number) {
const [user] = await this.drizzle.db
.delete(users)
.where(eq(users.id, id))
.returning();
if (!user) {
throw new NotFoundException(`User with ID ${id} not found`);
}
}
}npm install drizzle-orm pg
npm install -D drizzle-kit tsx @types/pg// drizzle.config.ts
import 'dotenv/config';
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
out: './drizzle',
schema: './src/db/schema.ts',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
});// src/db/schema.ts
import { pgTable, serial, varchar, timestamp } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: serial('id').primaryKey(),
email: varchar('email', { length: 255 }).notNull().unique(),
name: varchar('name', { length: 255 }).notNull(),
createdAt: timestamp('created_at').defaultNow(),
updatedAt: timestamp('updated_at').defaultNow(),
});// src/db/database.module.ts
import { Module } from '@nestjs/common';
import { DrizzleService } from './drizzle.service';
@Module({
providers: [DrizzleService],
exports: [DrizzleService],
})
export class DatabaseModule {}// src/auth/jwt.strategy.ts
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
@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, username: payload.username };
}
}// src/auth/jwt-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}// src/auth/roles.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { ROLES_KEY } from './roles.decorator';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<string[]>(ROLES_KEY, [
context.getHandler(),
context.getClass(),
]);
if (!requiredRoles) {
return true;
}
const { user } = context.switchToHttp().getRequest();
return requiredRoles.some((role) => user.roles?.includes(role));
}
}// src/auth/roles.decorator.ts
import { SetMetadata } from '@nestjs/common';
export const ROLES_KEY = 'roles';
export const Roles = (...roles: string[]) => SetMetadata(ROLES_KEY, roles);// src/users/users.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { UsersService } from './users.service';
import { DrizzleService } from '../drizzle/drizzle.service';
describe('UsersService', () => {
let service: UsersService;
let drizzle: DrizzleService;
const mockDrizzleService = {
db: {
insert: jest.fn().mockReturnValue({
values: jest.fn().mockReturnValue({
returning: jest.fn().mockResolvedValue([{ id: 1, email: 'test@example.com', name: 'Test' }]),
}),
}),
select: jest.fn().mockReturnValue({
from: jest.fn().mockReturnValue({
where: jest.fn().mockResolvedValue([{ id: 1, email: 'test@example.com', name: 'Test' }]),
}),
from: jest.fn().mockResolvedValue([{ id: 1, email: 'test@example.com', name: 'Test' }]),
}),
update: jest.fn().mockReturnValue({
set: jest.fn().mockReturnValue({
where: jest.fn().mockReturnValue({
returning: jest.fn().mockResolvedValue([{ id: 1, email: 'test@example.com', name: 'Test Updated' }]),
}),
}),
}),
delete: jest.fn().mockReturnValue({
where: jest.fn().mockReturnValue({
returning: jest.fn().mockResolvedValue([{ id: 1 }]),
}),
}),
},
};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UsersService,
{ provide: DrizzleService, useValue: mockDrizzleService },
],
}).compile();
service = module.get<UsersService>(UsersService);
drizzle = module.get<DrizzleService>(DrizzleService);
});
it('should create a user', async () => {
const createUserDto = { email: 'test@example.com', name: 'Test User' };
const result = await service.create(createUserDto);
expect(result).toEqual(expect.objectContaining({ email: 'test@example.com' }));
expect(drizzle.db.insert).toHaveBeenCalled();
});
it('should find all users', async () => {
const result = await service.findAll();
expect(result).toEqual(expect.any(Array));
expect(drizzle.db.select).toHaveBeenCalled();
});
it('should find a user by id', async () => {
const result = await service.findOne(1);
expect(result).toEqual(expect.objectContaining({ id: 1 }));
});
it('should throw NotFoundException when user not found', async () => {
jest.spyOn(drizzle.db, 'select').mockReturnValueOnce({
from: jest.fn().mockReturnValue({
where: jest.fn().mockResolvedValue([]),
}),
} as any);
await expect(service.findOne(999)).rejects.toThrow(NotFoundException);
});
});// src/users/users.controller.e2e-spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { UsersModule } from './users.module';
import { DrizzleService } from '../drizzle/drizzle.service';
describe('UsersController (e2e)', () => {
let app: INestApplication;
let drizzle: DrizzleService;
const mockDrizzleService = {
db: {
select: jest.fn().mockReturnValue({
from: jest.fn().mockResolvedValue([]),
}),
},
};
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [UsersModule],
})
.overrideProvider(DrizzleService)
.useValue(mockDrizzleService)
.compile();
app = moduleFixture.createNestApplication();
await app.init();
drizzle = moduleFixture.get<DrizzleService>(DrizzleService);
});
it('/users (GET)', () => {
return request(app.getHttpServer())
.get('/users')
.expect(200)
.expect([]);
});
it('/users (POST)', () => {
const createUserDto = {
email: 'test@example.com',
name: 'Test User',
};
return request(app.getHttpServer())
.post('/users')
.send(createUserDto)
.expect(201);
});
afterEach(async () => {
await app.close();
});
});// src/common/middleware/logging.middleware.ts
import { Injectable, NestMiddleware, Logger } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggingMiddleware implements NestMiddleware {
private logger = new Logger('HTTP');
use(req: Request, res: Response, next: NextFunction) {
const { ip, method, originalUrl } = req;
const userAgent = req.get('User-Agent') || '';
const startTime = Date.now();
res.on('finish', () => {
const { statusCode } = res;
const contentLength = res.get('Content-Length');
const duration = Date.now() - startTime;
this.logger.log(
`${method} ${originalUrl} ${statusCode} ${contentLength} - ${userAgent} ${ip} - ${duration}ms`,
);
});
next();
}
}// src/common/interceptors/transform.interceptor.ts
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export interface Response<T> {
data: T;
success: boolean;
timestamp: string;
}
@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,
success: true,
timestamp: new Date().toISOString(),
})),
);
}
}// src/users/dto/create-user.dto.ts
import { IsEmail, IsString, MinLength } from 'class-validator';
export class CreateUserDto {
@IsEmail()
email: string;
@IsString()
@MinLength(2)
name: string;
@IsString()
@MinLength(8)
password: string;
}// src/main.ts
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
transform: true,
transformOptions: {
enableImplicitConversion: true,
},
}),
);
await app.listen(3000);
}// src/config/configuration.ts
export default () => ({
port: parseInt(process.env.PORT, 10) || 3000,
database: {
host: process.env.DATABASE_HOST,
port: parseInt(process.env.DATABASE_PORT, 10) || 5432,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
},
jwt: {
secret: process.env.JWT_SECRET,
expiresIn: process.env.JWT_EXPIRES_IN || '1h',
},
});// src/config/config.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import configuration from './configuration';
@Module({
imports: [
ConfigModule.forRoot({
load: [configuration],
isGlobal: true,
}),
],
providers: [ConfigService],
exports: [ConfigService],
})
export class AppConfigModule {}// src/cache/cache.module.ts
import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { redisStore } from 'cache-manager-redis-store';
@Module({
imports: [
CacheModule.register({
store: redisStore,
host: 'localhost',
port: 6379,
}),
],
exports: [CacheModule],
})
export class AppCacheModule {}// src/common/guards/throttle.guard.ts
import { Injectable } from '@nestjs/common';
import { ThrottlerGuard } from '@nestjs/throttler';
@Injectable()
export class AppThrottlerGuard extends ThrottlerGuard {
protected errorMessage = 'Too many requests, please try again later.';
}// src/common/filters/http-exception.filter.ts
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
HttpStatus,
Logger,
} from '@nestjs/common';
import { Request, Response } from 'express';
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
private logger = new Logger(AllExceptionsFilter.name);
catch(exception: unknown, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
let status: number;
let message: string;
if (exception instanceof HttpException) {
status = exception.getStatus();
const exceptionResponse = exception.getResponse();
message = typeof exceptionResponse === 'string'
? exceptionResponse
: (exceptionResponse as any).message;
} else {
status = HttpStatus.INTERNAL_SERVER_ERROR;
message = 'Internal server error';
}
const errorResponse = {
success: false,
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
method: request.method,
message: message,
};
this.logger.error(
`${request.method} ${request.url}`,
JSON.stringify(errorResponse),
);
response.status(status).json(errorResponse);
}
}// src/main.ts
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.TCP,
options: {
host: '127.0.0.1',
port: 8877,
},
},
);
await app.listen();
}// src/math/math.controller.ts
import { Controller } from '@nestjs/common';
import { MessagePattern, Payload } from '@nestjs/microservices';
@Controller()
export class MathController {
@MessagePattern({ cmd: 'sum' })
accumulate(@Payload() data: number[]): number {
return (data || []).reduce((a, b) => a + b, 0);
}
}// src/graphql/graphql.module.ts
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
sortSchema: true,
playground: true,
introspection: true,
}),
],
})
export class GraphQLConfigModule {}// src/users/users.resolver.ts
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';
@Resolver(() => User)
export class UsersResolver {
constructor(private readonly usersService: UsersService) {}
@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)
createUser(@Args('createUserInput') createUserInput: CreateUserInput) {
return this.usersService.create(createUserInput);
}
}// src/main.ts
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('NestJS API')
.setDescription('The NestJS API description')
.setVersion('1.0')
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(3000);
}// src/users/users.controller.ts
import {
ApiTags,
ApiOperation,
ApiResponse,
ApiParam,
ApiBody
} from '@nestjs/swagger';
@ApiTags('users')
@Controller('users')
export class UsersController {
@ApiOperation({ summary: 'Get all users' })
@ApiResponse({ status: 200, description: 'Return all users', type: [User] })
@Get()
findAll() {
return this.usersService.findAll();
}
@ApiOperation({ summary: 'Get user by ID' })
@ApiParam({ name: 'id', description: 'User ID' })
@ApiResponse({ status: 200, description: 'Return user', type: User })
@Get(':id')
findOne(@Param('id') id: string) {
return this.usersService.findOne(id);
}
}src/
├── common/ # Shared utilities, filters, guards, interceptors
├── config/ # Configuration files
├── database/ # Database related files
├── auth/ # Authentication and authorization
├── users/ # User module (example)
│ ├── dto/ # Data transfer objects
│ ├── entities/ # Database entities
│ ├── interfaces/ # TypeScript interfaces
│ ├── tests/ # Test files
│ ├── users.controller.ts
│ ├── users.module.ts
│ └── users.service.ts
├── app.module.ts
└── main.ts*.module.ts, *.service.ts, *.controller.ts)Create reusable CRUD patterns using base classes or services to reduce code duplication.
Implement consistent pagination across all list endpoints using query parameters.
Add soft delete functionality to entities for data recovery capabilities.
Track create, update, and delete operations for compliance and debugging.
Use events to capture state changes for auditability and replay capabilities.
import {
WebSocketGateway,
SubscribeMessage,
MessageBody,
WebSocketServer,
} from '@nestjs/websockets';
import { Server } from 'socket.io';
@WebSocketGateway()
export class EventsGateway {
@WebSocketServer()
server: Server;
@SubscribeMessage('message')
handleMessage(@MessageBody() data: string): void {
this.server.emit('message', data);
}
}import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
@Injectable()
export class TasksService {
@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT)
handleDailyTask() {
// Daily task logic
}
}import {
Controller,
Post,
UseInterceptors,
UploadedFile,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
@Controller('files')
export class FilesController {
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
// File upload logic
}
}Implement health check endpoints for monitoring:
import { Controller, Get } from '@nestjs/common';
import { HealthCheckService, HealthCheck, HealthCheckResult } from '@nestjs/terminus';
@Controller('health')
export class HealthController {
constructor(private health: HealthCheckService) {}
@Get()
@HealthCheck()
check(): Promise<HealthCheckResult> {
return this.health.check([]);
}
}Implement structured logging for production:
import { LoggerService } from '@nestjs/common';
export class AppLogger implements LoggerService {
log(message: any, context?: string) {
// Structured logging implementation
}
}Create Dockerfile for containerization:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/main"]This guide provides a comprehensive overview of NestJS development patterns available in the Developer Kit. By following these patterns and best practices, you can build scalable, maintainable, and secure enterprise applications.
For specific implementation details and advanced patterns, refer to the NestJS skill and the official NestJS documentation.
docs
plugins
developer-kit-ai
developer-kit-aws
agents
docs
skills
aws
aws-cli-beast
aws-cost-optimization
aws-drawio-architecture-diagrams
aws-sam-bootstrap
aws-cloudformation
aws-cloudformation-auto-scaling
aws-cloudformation-bedrock
aws-cloudformation-cloudfront
aws-cloudformation-cloudwatch
aws-cloudformation-dynamodb
aws-cloudformation-ec2
aws-cloudformation-ecs
aws-cloudformation-elasticache
references
aws-cloudformation-iam
references
aws-cloudformation-lambda
aws-cloudformation-rds
aws-cloudformation-s3
aws-cloudformation-security
aws-cloudformation-task-ecs-deploy-gh
aws-cloudformation-vpc
references
developer-kit-core
agents
commands
skills
developer-kit-devops
developer-kit-java
agents
commands
docs
skills
aws-lambda-java-integration
aws-rds-spring-boot-integration
aws-sdk-java-v2-bedrock
aws-sdk-java-v2-core
aws-sdk-java-v2-dynamodb
aws-sdk-java-v2-kms
aws-sdk-java-v2-lambda
aws-sdk-java-v2-messaging
aws-sdk-java-v2-rds
aws-sdk-java-v2-s3
aws-sdk-java-v2-secrets-manager
clean-architecture
graalvm-native-image
langchain4j-ai-services-patterns
references
langchain4j-mcp-server-patterns
references
langchain4j-rag-implementation-patterns
references
langchain4j-spring-boot-integration
langchain4j-testing-strategies
langchain4j-tool-function-calling-patterns
langchain4j-vector-stores-configuration
references
qdrant
references
spring-ai-mcp-server-patterns
spring-boot-actuator
spring-boot-cache
spring-boot-crud-patterns
spring-boot-dependency-injection
spring-boot-event-driven-patterns
spring-boot-openapi-documentation
spring-boot-project-creator
spring-boot-resilience4j
spring-boot-rest-api-standards
spring-boot-saga-pattern
spring-boot-security-jwt
assets
references
scripts
spring-boot-test-patterns
spring-data-jpa
references
spring-data-neo4j
references
unit-test-application-events
unit-test-bean-validation
unit-test-boundary-conditions
unit-test-caching
unit-test-config-properties
references
unit-test-controller-layer
unit-test-exception-handler
references
unit-test-json-serialization
unit-test-mapper-converter
references
unit-test-parameterized
unit-test-scheduled-async
references
unit-test-service-layer
references
unit-test-utility-methods
unit-test-wiremock-rest-api
references
developer-kit-php
developer-kit-project-management
developer-kit-python
developer-kit-specs
commands
docs
hooks
test-templates
tests
skills
developer-kit-tools
developer-kit-typescript
agents
docs
hooks
rules
skills
aws-cdk
aws-lambda-typescript-integration
better-auth
clean-architecture
drizzle-orm-patterns
dynamodb-toolbox-patterns
references
nestjs
nestjs-best-practices
nestjs-code-review
nestjs-drizzle-crud-generator
nextjs-app-router
nextjs-authentication
nextjs-code-review
nextjs-data-fetching
nextjs-deployment
nextjs-performance
nx-monorepo
react-code-review
react-patterns
shadcn-ui
tailwind-css-patterns
tailwind-design-system
references
turborepo-monorepo
typescript-docs
typescript-security-review
zod-validation-utilities
references
github-spec-kit