Create clean, well-structured REST APIs using NestJS conventions and best practices.
Welcome to Controllers & Routing in NestJS! This chapter will teach you how to design and implement RESTful APIs using NestJS's powerful routing system. You'll learn about route handlers, parameter decorators, and best practices for building scalable APIs.
A controller in NestJS is a class that contains methods (called handlers) which handle HTTP requests. These handlers are mapped to specific routes using decorators like @Get, @Post, etc.
import { Controller, Get } from '@nestjs/common';
@Controller('tasks')
export class TasksController {
@Get()
findAll() {
return ['Task 1', 'Task 2'];
}
}
@Get(':id')
findOne(@Param('id') id: string) {
return `This action returns a #${id} task`;
}
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
@Controller('users')
export class UsersController {
@Get()
findAll() {
return ['User 1', 'User 2'];
}
@Post()
create(@Body() user: CreateUserDto) {
return { message: 'User created successfully' };
}
@Get(':id')
findOne(@Param('id') id: string) {
return `Profile of user #${id}`;
}
}
Welcome to the chapter on Services & Dependency Injection in NestJS! This is a crucial part of building scalable and maintainable applications. You'll learn how to encapsulate business logic, manage dependencies effectively, and follow best practices for clean architecture.
In NestJS, services are the workhorses of your application. They handle all the business logic and domain operations, keeping your controllers lean and focused on handling HTTP requests.
To create a service in NestJS, you use the @Injectable() decorator. This marks the class as a service that can be injected into other components.
import { Injectable } from '@nestjs/common';
@Injectable()
export class UserService {
// Business logic methods go here
}
Dependency injection (DI) allows you to inject dependencies into your services through the constructor. This makes your code more modular and easier to test.
import { Injectable } from '@nestjs/common';
@Injectable()
export class UserService {
constructor(private readonly repository: UserRepository) {}
findAll(): User[] {
return this.repository.findAll();
}
}
Imagine a user management system where users can be created, read, updated, and deleted. The service layer would handle all the data manipulation logic while the controller simply passes the request to the service.
// Controller
@app.post('/users')
async createUser(@body() userDto: CreateUserDto) {
return this.userService.create(userDto);
}
// Service
@Injectable()
export class UserService {
constructor(private userRepository: UserRepository) {}
async create(createUserDto: CreateUserDto): Promise<User> {
const existingUser = await this.userRepository.findByEmail(createUserDto.email);
if (existingUser) throw new ConflictError('User already exists');
return this.userRepository.create(createUserDto);
}
}
Question 1 of 9