A Class Whose Methods Are Route Handlers
Controllers — HTTP Request Handlers
Controllers receive incoming HTTP requests and return responses. Methods are decorated with HTTP verbs to bind them to routes.
What you'll learn
- Decorate a class with `@Controller('path')`
- Define `@Get`/`@Post` handlers
- Let return values auto-serialize to JSON
A controller in Nest is just a class. Its methods become HTTP handlers
when you decorate them with verb decorators. The class itself gets a route
prefix from @Controller().
Your First Controller
import { Controller, Get, Post, Body } from '@nestjs/common';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly users: UsersService) {}
@Get()
list() {
return this.users.findAll();
}
@Post()
create(@Body() body: { name: string }) {
return this.users.create(body.name);
}
} That class declares two endpoints:
GET /usersreturnsusers.findAll()POST /usersreads the JSON body and callsusers.create()
Auto-Serialization
You don’t call res.json(...) or set Content-Type. Whatever your method
returns (object, array, string, number) Nest serializes to JSON and sends
back with a 200 for @Get or 201 for @Post. Returning a Promise
works too — Nest awaits it.
Constructor Injection
Notice how UsersService arrives via the constructor. The private readonly shorthand creates the field and assigns it in one line. Nest’s
DI container does the wiring; you never new UsersService() yourself.
Registering the Controller
A controller only handles routes after you list it in a module:
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {} If a controller seems “dead” — request hits 404 — almost always the fix is adding it to a module that gets loaded.
Quick Sanity Check
curl http://localhost:3000/users
curl -X POST http://localhost:3000/users \
-H 'content-type: application/json' \
-d '{"name":"Ada"}' That’s enough to see both handlers fire. From here it’s all about adding more decorators to shape the request/response.
Providers & Services →