
Top Next.JS Code Snippets Every Developer Should Know
NestJS has rapidly become a go-to framework for building scalable and maintainable server-side applications with Node.js. Its modular architecture, TypeScript support, and dependency injection system make it a favorite among developers. To maximize your productivity and write cleaner code, mastering essential code snippets is crucial. This post highlights some of the most valuable NestJS snippets you'll use repeatedly.
1. Basic Controller Setup
Controllers handle incoming requests and return responses. This is a fundamental snippet you'll use in every route.
import { Controller, Get, Post, Body, Param, Delete } from '@nestjs/common';
@Controller('products')
export class ProductsController {
@Get()
findAll(): string {
return 'This action returns all products';
}
@Get(':id')
findOne(@Param('id') id: string): string {
return `This action returns a #${id} product`;
}
@Post()
create(@Body() body: any): string {
console.log(body);
return 'This action adds a new product';
}
@Delete(':id')
remove(@Param('id') id: string): string {
return `This action removes a #${id} product`;
}
}
This snippet demonstrates how to define different HTTP methods (GET, POST, DELETE) and extract request parameters using @Param
and @Body
decorators.
2. Creating a Service with Dependency Injection
Services encapsulate business logic and are injected into controllers (and other services) using NestJS's dependency injection.
import { Injectable } from '@nestjs/common';
@Injectable()
export class ProductsService {
private readonly products: any[] = [];
create(product: any) {
this.products.push(product);
}
findAll(): any[] {
return this.products;
}
findOne(id: number): any {
// Implement your findOne logic here
return this.products.find(product => product.id === id)
}
}
To use this service in a controller, you'll need to inject it:
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { ProductsService } from './products.service';
@Controller('products')
export class ProductsController {
constructor(private readonly productsService: ProductsService) {}
@Post()
create(@Body() product: any) {
this.productsService.create(product);
}
@Get()
findAll() {
return this.productsService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.productsService.findOne(Number(id));
}
}
3. Using Mongoose for Database Interaction
NestJS integrates seamlessly with Mongoose for MongoDB interactions. First, import necessary modules.
import { MongooseModule } from '@nestjs/mongoose';
import { Module } from '@nestjs/common';
import { Product, ProductSchema } from './schemas/product.schema';
import { ProductsService } from './products.service';
import { ProductsController } from './products.controller';
@Module({
imports: [MongooseModule.forRoot('mongodb://localhost/nest'),
MongooseModule.forFeature([{ name: Product.name, schema: ProductSchema }])],
controllers: [ProductsController],
providers: [ProductsService],
})
export class AppModule {}
Then, inject the model into your service:
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Product, ProductDocument } from './schemas/product.schema';
@Injectable()
export class ProductsService {
constructor(@InjectModel(Product.name) private productModel: Model<ProductDocument>) {}
async create(product: Product): Promise<Product> {
const createdProduct = new this.productModel(product);
return createdProduct.save();
}
async findAll(): Promise<Product[]> {
return this.productModel.find().exec();
}
}
4. Validation with Pipes
NestJS provides powerful validation pipes to ensure data integrity. Here's how to use the built-in ValidationPipe
:
import { Controller, Post, Body, UsePipes, ValidationPipe } from '@nestjs/common';
class CreateProductDto {
name: string;
price: number;
}
@Controller('products')
export class ProductsController {
@Post()
@UsePipes(new ValidationPipe())
create(@Body() createProductDto: CreateProductDto) {
// ... your logic here
}
}
You also need to create a DTO (Data Transfer Object) and use class-validator decorators to define validation rules.
import { IsString, IsNumber, IsNotEmpty } from 'class-validator';
export class CreateProductDto {
@IsString()
@IsNotEmpty()
name: string;
@IsNumber()
@IsNotEmpty()
price: number;
}
5. Exception Filters
Exception filters allow you to handle exceptions globally and provide consistent error responses.
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,
message: exception.message,
});
}
}
Don't forget to bind the exception filter in your main.ts or app.module.ts.
Conclusion
These code snippets represent some of the most common patterns you'll encounter when building NestJS applications. Mastering them will significantly boost your development speed and improve the overall quality of your code. As you continue to explore NestJS, remember to leverage its powerful features and built-in tools for creating robust and scalable applications.
Comments
Login to write a comment