A Nest controller is a class decorated with @Controller that defines HTTP routes and delegates request handling to injected providers, returning data or throwing an HTTP exception.
In simpler words
A controller matches an incoming URL and method, hands the real work to a service, and sends back whatever that service returns.
Controllers are the HTTP front door of every Nest module. Keep them thin — parsing, delegating, responding — never doing business logic or raw SQL themselves.
Predict a full route (method + path) from @Controller + @Get/@Post/etc.
Read param decorators (@Param, @Query, @Body, @CurrentUser) and know what each extracts
Explain why TicketsController has no @UseGuards despite being protected
Return data vs throw an HTTP exception correctly
Routing by decoration
Definition
Nest route decorators such as @Controller, @Get, @Post, @Patch, and @Delete attach a URL prefix and HTTP-method-specific path segment that together determine which method handles a request.
In simpler words
The class-level @Controller("tickets") sets the prefix; each method’s @Get/@Post/etc. adds the rest of the path for that HTTP verb.
@Controller("tickets") + @Get() on a method becomes GET /tickets. @Get(":id") on another becomes GET /tickets/:id. @Delete(":id") becomes DELETE /tickets/:id.
Route order inside the class does not matter for matching — Nest matches by method + path pattern, not by declaration order (though more specific static paths should still be declared before broad wildcard ones if both exist).
Five decorated methods, five distinct routes — no manual router.get()/post() wiring anywhere.
Extracting request data with param decorators
Definition
Parameter decorators such as @Param, @Query, @Body, and custom decorators like @CurrentUser instruct Nest to extract a specific piece of the incoming request and pass it as a typed method argument, often after pipes have validated or transformed it.
In simpler words
@Param reads a URL segment, @Query reads the query string, @Body reads the JSON body, and @CurrentUser reads the authenticated user — each becomes a plain typed argument.
@Param("id", ParseUUIDPipe) both extracts :id from the URL and runs ParseUUIDPipe on it before the handler runs — a bad UUID never reaches TicketsService.
@Query() and @Body() bind the whole query string or JSON body to a DTO class (ListTicketsQueryDto, CreateTicketDto), which the global ValidationPipe then validates.
Health controller — the simplest possible controller
@Req() escapes Nest’s pipeline — the global ValidationPipe never runs on manually read fields.
Return values, status codes, and auth without @UseGuards
Definition
Nest serializes a route handler’s return value into a JSON HTTP response with a default status code per HTTP method, and maps thrown Nest HTTP exceptions to an error response through the registered exception filter.
In simpler words
Return an object and Nest sends JSON (201 for POST, 200 for others by default, unless you override it); throw a Nest exception and the filter turns it into a consistent error body.
TicketsController has no @UseGuards(...) anywhere, yet every non-@Public route is protected — because JwtAuthGuard is registered globally as APP_GUARD in AuthModule, so it runs on every route unless that route is marked @Public().
@Roles("admin") on remove() works the same way: RolesGuard is also a global APP_GUARD that reads the @Roles metadata and checks the authenticated user’s role before the handler runs.
@HttpCode(HttpStatus.NO_CONTENT) on remove() overrides the default 200 to 204, matching a delete that returns no body.