
Controllers
- 2 installs
- 1 repo stars
- Updated January 2, 2026
- ramziddin/ccplugins
Reference for NestJS controllers: routing, HTTP methods, route and query parameters, request bodies, and responses.
About
Covers building REST API endpoints in NestJS with controllers, decorators, routing, and request/response handling. A developer uses it when creating HTTP endpoints or handling route data.
- Maps routes with @Controller and HTTP-method decorators
- Handles params, query, body, headers, status codes, and redirects
Controllers by the numbers
- 2 all-time installs (skills.sh)
- Ranked #3,765 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/ramziddin/ccplugins --skill controllersAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2 |
|---|---|
| repo stars | ★ 1 |
| Last updated | January 2, 2026 |
| Repository | ramziddin/ccplugins ↗ |
What it does
Reference for NestJS controllers: routing, HTTP methods, route and query parameters, request bodies, and responses.
Files
NestJS Controllers
When to Use This Skill
Use this skill when:
- Creating REST API endpoints
- Handling HTTP requests (GET, POST, PUT, DELETE, PATCH)
- Working with route parameters, query parameters, or request bodies
- Setting up routing and path prefixes
- Handling redirects, headers, or status codes
- Working with async/await in route handlers
What are Controllers?
Controllers are responsible for handling incoming requests and returning responses to the client. They use decorators to map routes to handler methods.
Basic Controller
import { Controller, Get } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get()
findAll(): string {
return 'This action returns all cats';
}
}Key Points:
@Controller('cats')- Sets route prefix/cats@Get()- Maps GET requests to this method- Returns value automatically serialized to JSON (objects/arrays)
- Must register controller in module's
controllersarray
HTTP Method Decorators
import { Controller, Get, Post, Put, Delete, Patch } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get()
findAll() {
return [];
}
@Post()
create() {
return 'Created';
}
@Put(':id')
update() {
return 'Updated';
}
@Delete(':id')
remove() {
return 'Deleted';
}
@Patch(':id')
patch() {
return 'Patched';
}
}Route Parameters
import { Controller, Get, Param } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get(':id')
findOne(@Param('id') id: string) {
return `This action returns cat #${id}`;
}
// Multiple parameters
@Get(':category/:id')
findByCategory(
@Param('category') category: string,
@Param('id') id: string
) {
return `Category: ${category}, ID: ${id}`;
}
// All params as object
@Get(':id')
findOneAlt(@Param() params: { id: string }) {
return `Cat #${params.id}`;
}
}Query Parameters
import { Controller, Get, Query } from '@nestjs/common';
@Controller('cats')
export class CatsController {
// /cats?limit=10&offset=0
@Get()
findAll(
@Query('limit') limit: string,
@Query('offset') offset: string
) {
return `Limit: ${limit}, Offset: ${offset}`;
}
// All query params as object
@Get()
findAllAlt(@Query() query: { limit: string; offset: string }) {
return query;
}
}Request Body
import { Controller, Post, Body } from '@nestjs/common';
export class CreateCatDto {
name: string;
age: number;
breed: string;
}
@Controller('cats')
export class CatsController {
@Post()
create(@Body() createCatDto: CreateCatDto) {
return `Creating cat: ${createCatDto.name}`;
}
// Specific property
@Post()
createAlt(@Body('name') name: string) {
return `Creating cat: ${name}`;
}
}Request Object
import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';
@Controller('cats')
export class CatsController {
@Get()
findAll(@Req() request: Request) {
return request.headers;
}
}Available Request Decorators:
@Request(), @Req()- Full request object@Response(), @Res()- Full response object (use with caution)@Next()- Next function@Session()- Session object@Param(key?)- Route parameters@Body(key?)- Request body@Query(key?)- Query parameters@Headers(key?)- Request headers@Ip()- Client IP address@HostParam()- Host parameters
Status Codes
import { Controller, Post, HttpCode, HttpStatus } from '@nestjs/common';
@Controller('cats')
export class CatsController {
// Default: 200 for GET, 201 for POST
@Post()
create() {
return 'Created';
}
// Custom status code
@Post()
@HttpCode(HttpStatus.NO_CONTENT)
createNoContent() {
// Returns 204
}
@Post()
@HttpCode(204)
createAlt() {
// Also returns 204
}
}Response Headers
import { Controller, Post, Header } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Post()
@Header('Cache-Control', 'no-store')
@Header('X-Custom-Header', 'value')
create() {
return 'Created with custom headers';
}
}Redirection
import { Controller, Get, Redirect } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get('docs')
@Redirect('https://docs.nestjs.com', 301)
getDocs() {
// Redirects to docs
}
// Dynamic redirect
@Get('search')
@Redirect()
search(@Query('term') term: string) {
return {
url: `https://google.com/search?q=${term}`,
statusCode: 302
};
}
}Route Wildcards
import { Controller, Get } from '@nestjs/common';
@Controller('cats')
export class CatsController {
// Matches: /cats/profile, /cats/p, /cats/prxfile
@Get('ab*cd')
findWildcard() {
return 'Wildcard route';
}
}Supported wildcards: *, ?, +, ()
Sub-Domain Routing
import { Controller, Get, HostParam } from '@nestjs/common';
@Controller({ host: ':account.example.com' })
export class AccountController {
@Get()
getInfo(@HostParam('account') account: string) {
return `Account: ${account}`;
}
}Async Handlers
import { Controller, Get } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get()
async findAll(): Promise<Cat[]> {
return await this.catsService.findAll();
}
// Using Observables (RxJS)
@Get()
findAllRx(): Observable<Cat[]> {
return of([]);
}
}DTOs (Data Transfer Objects)
// create-cat.dto.ts
export class CreateCatDto {
name: string;
age: number;
breed: string;
}
// cats.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
@Controller('cats')
export class CatsController {
@Post()
create(@Body() createCatDto: CreateCatDto) {
return createCatDto;
}
}Why use classes instead of interfaces?
- Classes are preserved at runtime (interfaces are not)
- Enables validation with
class-validator - Works with Pipes for transformation
Complete Controller Example
import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
Query,
HttpCode,
HttpStatus,
} from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { UpdateCatDto } from './dto/update-cat.dto';
import { CatsService } from './cats.service';
@Controller('cats')
export class CatsController {
constructor(private readonly catsService: CatsService) {}
@Get()
findAll(@Query('limit') limit = 10) {
return this.catsService.findAll(limit);
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.catsService.findOne(id);
}
@Post()
@HttpCode(HttpStatus.CREATED)
create(@Body() createCatDto: CreateCatDto) {
return this.catsService.create(createCatDto);
}
@Put(':id')
update(
@Param('id') id: string,
@Body() updateCatDto: UpdateCatDto
) {
return this.catsService.update(id, updateCatDto);
}
@Delete(':id')
@HttpCode(HttpStatus.NO_CONTENT)
remove(@Param('id') id: string) {
return this.catsService.remove(id);
}
}Registering Controllers
Controllers must be registered in a module:
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {}Best Practices
1. Keep controllers thin - Delegate business logic to services 2. Use DTOs - Define classes for request/response data 3. Validate input - Use ValidationPipe with class-validator 4. Use dependency injection - Inject services via constructor 5. Handle errors properly - Throw appropriate HTTP exceptions 6. Use async/await - For asynchronous operations 7. Document APIs - Use @nestjs/swagger for OpenAPI docs 8. Consistent naming - Use standard REST conventions
Common Patterns
Resource Controller Pattern
nest generate resource catsThis generates:
- Module
- Controller with CRUD routes
- Service
- DTOs (create, update)
- Entity
Nested Routes
@Controller('users/:userId/posts')
export class PostsController {
@Get()
findUserPosts(@Param('userId') userId: string) {
return this.postsService.findByUser(userId);
}
}Versioning
import { Controller, Version } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Version('1')
@Get()
findAllV1() {
return 'V1';
}
@Version('2')
@Get()
findAllV2() {
return 'V2';
}
}