Controllers

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 7 min

Controllers are the entry point for handling incoming HTTP requests and returning responses to the client.

Overview

A controller’s sole purpose is to receive specific requests for the application. The routing mechanism controls which controller receives which requests.

Controllers are defined using classes and the @Controller() decorator. The decorator allows you to define a route path prefix for all routes defined within that class, making it easy to group a set of related routes.

Key Concepts

  • @Controller(prefix?): The decorator that defines a controller. You can optionally pass a string prefix (e.g., 'users').
  • Route Handlers: Methods inside the controller class annotated with HTTP method decorators (@Get, @Post, etc.).
  • Dependency Injection: Controllers usually inject a Service via the constructor to handle the actual business logic.

Code Examples

A Basic Controller

This controller handles requests matching the /cats path.

import { Controller, Get, Post } from '@nestjs/common';
import { CatsService } from './cats.service';

// The prefix is 'cats'
@Controller('cats')
export class CatsController {
  
  // Inject the service
  constructor(private catsService: CatsService) {}

  // Handles GET /cats
  @Get()
  findAll(): string {
    return this.catsService.findAll();
  }

  // Handles POST /cats
  @Post()
  create(): string {
    return this.catsService.create();
  }
}

Async Handlers

NestJS route handlers can be either synchronous or asynchronous. Nest automatically resolves promises and observables.

@Get()
async findAll(): Promise<any[]> {
  // Nest will wait for the promise to resolve before returning the response
  return this.catsService.findAllAsync();
}

Standard Responses

By default, Nest handles the HTTP response serialization for you:

  • If you return an object or array, it serializes it to JSON.
  • If you return a primitive (string, number, boolean), it sends just the value.
  • It sets the status code to 200 OK (except for POST requests, which use 201 Created).

Best Practices

  • Thin Controllers: Controllers should not contain business logic. They should only handle HTTP routing, extract the necessary data (using DTOs and Params), pass it to a Service, and return the result.
  • RESTful Naming Conventions: Group controllers by resource (e.g., UsersController, ProductsController) and use standard HTTP methods to manipulate those resources.