Creating and updating resources requires reading structured data from the request body. This lesson covers @Body(), pairing it with a DTO class, and how validation fits into the flow.
Reading a JSON Request Body
The @Body() decorator extracts the parsed request body, populated automatically by Nest's built-in body-parsing middleware for JSON payloads. Pairing it with a typed DTO class gives you both compile-time typing and, combined with ValidationPipe, runtime validation.
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;
}
}
CreateCatDto describes the expected shape of the body. Without ValidationPipe, this only provides compile-time typing, the runtime object is not automatically checked against the class.
@Body() with no argument returns the entire parsed request body.
@Body('field') extracts a single named field from the body.
Nest's global ValidationPipe (or a route-level one) enforces a DTO's validation rules at runtime.
Request bodies require Content-Type: application/json (or the appropriate parser) to be populated.
Request Body Cheatsheet
Common patterns for reading and validating request bodies.
Usage
Result
@Body() dto: CreateCatDto
The entire body, typed as a DTO
@Body('name') name: string
A single field from the body
@Body() dto: CreateCatDto + global ValidationPipe
Body validated against DTO rules
@Put() / @Patch() + UpdateCatDto
Full vs. partial update payloads
Defining the Expected Shape With a DTO
A DTO (Data Transfer Object) class describes exactly which fields a request body should contain and their types, giving both the compiler and, with class-validator decorators, the runtime a single source of truth.
import { IsString, IsInt, Min } from 'class-validator';
export class CreateCatDto {
@IsString()
name: string;
@IsInt()
@Min(0)
age: number;
@IsString()
breed: string;
}
This same class is used purely for typing without ValidationPipe, but becomes a full runtime validator once ValidationPipe is enabled globally or on this route.
Full Updates vs. Partial Updates
A PUT request typically expects the entire resource representation in the body (a full replace), while PATCH expects only the fields being changed. NestJS models this with two DTOs, often generating the partial one from the full one using PartialType().
import { PartialType } from '@nestjs/mapped-types';
import { CreateCatDto } from './create-cat.dto';
export class UpdateCatDto extends PartialType(CreateCatDto) {}
Common Mistakes
Trusting the request body's shape without enabling ValidationPipe, the DTO alone offers no runtime protection.
Using the same DTO for both create and update operations when their required fields actually differ.
Not handling malformed JSON bodies, which Nest's body parser rejects automatically with a 400.
Exposing internal or sensitive fields on a DTO that shouldn't be settable by clients.
Key Takeaways
@Body() reads the parsed JSON request body, either fully or by field.
DTO classes describe the expected body shape and, with class-validator, its runtime rules.
ValidationPipe is what actually enforces a DTO's validation rules at runtime.
PartialType() derives an update DTO from a create DTO without duplicating field definitions.
Pro Tip
Never reuse a create DTO directly as an update DTO without wrapping it in PartialType(), otherwise every PATCH request will be rejected for "missing" fields the client never intended to change.
You now know how to read and structure request bodies. Next, put it all together by building a NestJS REST API.