Table of Contents
- Introduction to Controllers
- Role of Controllers in the Request-Response Cycle
- Creating a Controller with
@Controller()
- HTTP Methods:
@Get()
,@Post()
,@Put()
,@Delete()
, etc. - Route Parameters and Dynamic Routing
- Query Parameters and Request Body Handling
- Response Customization with
@Res()
- Status Codes and Exception Handling in Controllers
- Using Services in Controllers via Dependency Injection
- Organizing Routes and RESTful Design
- Summary and What’s Next
1. Introduction to Controllers
In NestJS, controllers handle incoming HTTP requests and return responses to the client. They are the entry points to your application’s API layer.
A controller is a class annotated with the @Controller()
decorator. You define routes and attach them to HTTP method handlers within these classes.
2. Role of Controllers in the Request-Response Cycle
Here’s how a request flows through NestJS:
- HTTP request hits a defined route.
- Nest routes it to the corresponding controller method.
- Controller delegates business logic to a service.
- Service performs logic, returns result.
- Controller sends response back to the client.
Controllers don’t hold business logic — they delegate it to providers (usually services).
3. Creating a Controller with @Controller()
To create a controller manually:
nest g controller users
Or by hand:
import { Controller } from '@nestjs/common';
@Controller('users')
export class UsersController {}
The string 'users'
defines a route prefix. Every method inside will automatically be prefixed with /users
.
4. HTTP Methods in NestJS
You use decorators like @Get()
, @Post()
, etc. to define routes.
@Controller('users')
export class UsersController {
@Get()
findAll() {
return 'This action returns all users';
}
@Post()
create() {
return 'This action creates a user';
}
@Put(':id')
update(@Param('id') id: string) {
return `This updates user with ID: ${id}`;
}
@Delete(':id')
remove(@Param('id') id: string) {
return `User ${id} deleted`;
}
}
5. Route Parameters and Dynamic Routing
Use @Param()
to get dynamic route variables:
@Get(':id')
getUser(@Param('id') id: string) {
return `Fetching user with ID ${id}`;
}
You can also use a DTO for complex param validation with Pipes (discussed in later modules).
6. Query Parameters and Request Body Handling
- Query Strings: Use
@Query()
decorator
@Get()
getByQuery(@Query('role') role: string) {
return `Users with role: ${role}`;
}
- Request Body: Use
@Body()
@Post()
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}
7. Response Customization with @Res()
Sometimes you need fine-grained control over the response object:
@Get()
customResponse(@Res() res: Response) {
res.status(200).json({ message: 'Hello from NestJS!' });
}
Note: Using @Res()
makes the route handler incompatible with interceptors or automatic response transformation.
8. Status Codes and Exception Handling in Controllers
Set custom HTTP status codes using decorators:
@Post()
@HttpCode(201)
createUser() {
return { message: 'User created' };
}
Throw errors using built-in exceptions:
@Get(':id')
getUser(@Param('id') id: string) {
if (!user) {
throw new NotFoundException(`User ${id} not found`);
}
return user;
}
9. Using Services in Controllers via Dependency Injection
A controller shouldn’t contain business logic. Inject a service:
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll() {
return this.usersService.findAll();
}
}
Nest will inject the corresponding service if it’s declared in the same or imported module.
10. Organizing Routes and RESTful Design
Follow RESTful best practices:
GET /users
: List all usersGET /users/:id
: Get a user by IDPOST /users
: Create a new userPUT /users/:id
: Update a userDELETE /users/:id
: Remove a user
Structure controllers around features, not HTTP verbs.
11. Summary and What’s Next
In this module, you’ve learned:
- How to define routes and controllers in NestJS
- How to handle route and query parameters
- How to respond to HTTP requests using decorators
- How to inject services into controllers