Updated on 16 Dec, 202518 mins read 21 views

What Are Controllers?

Imagine you are a pizza place. You tell the waiter: "I would like a large pepperoni pizza."

The waiter:

  1. Listens to your order
  2. Understands what you want
  3. Tells the kitchen to make it
  4. Brings you the pizza

In NestJS, controllers do exactly this for HTTP requests.

// Real-world analogy in code:
@Controller('pizza')  // The "Pizza Department" of your restaurant
export class PizzaController {
  @Get('pepperoni')   // When someone asks for pepperoni pizza
  getPepperoniPizza() {
    return 'Here is your delicious pepperoni pizza! 🍕';
  }
}

Your First Controller: Hello World

Let's create the simplest possible controller together:

// app.controller.ts
import { Controller, Get } from '@nestjs/common';

@Controller()  // This makes it a controller!
export class AppController {
  
  @Get()  // Handles GET requests to the homepage
  sayHello(): string {
    return 'Hello, World! Welcome to my NestJS app!';
  }
  
  @Get('about')  // Handles GET requests to /about
  getAboutPage(): string {
    return 'This is my amazing app!';
  }
}

What just happened?

  • @Controller(): Makes this class a controller
  • @Get(): Handles GET requests
  • @Get('about'): Handles GET requests to /about

Try it, if you run this and visit:

  • http://localhost:3000: You will see “Hello, World!”
  • http://localhost:3000/about: You will see “This is my amazing app!”

Route Paths: The Address System

Controllers can handle requests to different “addresses” (URLs):

@Controller('users')  // All routes here start with /users
export class UsersController {
  
  @Get()          // GET /users
  getAllUsers() { /* ... */ }
  
  @Get('profile') // GET /users/profile  
  getUserProfile() { /* ... */ }
  
  @Get(':id')     // GET /users/123 (dynamic!)
  getUserById() { /* ... */ }
}

HTTP Methods: Different Types of Requests

Controllers handle different request types:

@Controller('tasks')
export class TasksController {
  
  @Get()          // Get all tasks (READ)
  getTasks() { return 'All tasks'; }
  
  @Post()         // Create a task (CREATE)
  createTask() { return 'Task created'; }
  
  @Put(':id')     // Update a task (UPDATE)
  updateTask() { return 'Task updated'; }
  
  @Delete(':id')  // Delete a task (DELETE)
  deleteTask() { return 'Task deleted'; }
  
  @Patch(':id')   // Partially update a task
  partialUpdate() { return 'Task partially updated'; }
}

These correspond to CRUD operations:

  • Create -> @Post()
  • Read -> @Get()
  • Update -> @Put() or @Patch()
  • Delete -> @Delete()

How Controllers Receive Information

When someone sends data to your app (like filling out a form), controllers need to receive it. Here are all the ways:

1 Route Parameters: Data in the URL

@Get('users/:id')  // The :id is a route parameter
getUser(@Param('id') userId: string) {
  return `Fetching user with ID: ${userId}`;
}

// Example: GET /users/123
// Output: "Fetching user with ID: 123"

2 Query Parameters: Filters and Options

@Get('products')
getProducts(
  @Query('page') page: number,
  @Query('limit') limit: number,
  @Query('category') category?: string
) {
  return `Page: ${page}, Limit: ${limit}, Category: ${category || 'all'}`;
}

// Example: GET /products?page=1&limit=10&category=books
// Output: "Page: 1, Limit: 10, Category: books"

3 Request Body: The Main Data

@Post('users')
createUser(@Body() userData: any) {
  return `Creating user: ${JSON.stringify(userData)}`;
}

// Example POST to /users with body: {"name": "John", "email": "john@example.com"}
// Output: "Creating user: {"name":"John","email":"john@example.com"}"

4 Headers: Metadata About the Request

@Get('secure-data')
getSecureData(@Headers('authorization') authToken: string) {
  if (authToken === 'secret-token') {
    return 'Here is your secure data!';
  }
  return 'Access denied!';
}

5 Everything Together: The Complete Picture

@Put('products/:id')
updateProduct(
  @Param('id') productId: string,
  @Body() updateData: any,
  @Query('version') version: string
) {
  return {
    message: `Updating product ${productId}`,
    data: updateData,
    apiVersion: version
  };
}

Sending Responses: How Controllers Reply

Controllers don't just receive data – they send it back too.

1 Basic Responses

@Get()
getMessage() {
  return 'Hello World';  // Automatic 200 status code
}

@Get('not-found')
getNotFound() {
  throw new NotFoundException('Item not found');  // 404 error
}

@Post('created')
createItem() {
  // Return 201 Created with location header
  return new CreatedResponse('Item created', { id: 1 });
}

2 Status Codes

import { HttpCode } from '@nestjs/common';

@Post('custom-status')
@HttpCode(201)  // Set custom status code
createWithCustomStatus() {
  return { message: 'Created successfully' };
}

@Get('no-content')
@HttpCode(204)  // No Content
deleteItem() {
  // No response body for 204
}

3 Headers in Responses

import { Header } from '@nestjs/common';

@Get('download')
@Header('Content-Type', 'application/pdf')
@Header('Content-Disposition', 'attachment; filename="report.pdf"')
downloadFile() {
  // Return file content
  return Buffer.from('PDF content here');
}

 

Buy Me A Coffee

Leave a comment

Your email address will not be published. Required fields are marked *