Pipes
NestJS pipes validate and transform input data before it reaches your procedure handler.
Usage with Zod
When you define a Zod schema on a procedure, input validation happens automatically:
@Mutation({ input: z.object({ name: z.string().min(1) }) })
create(@Input() input: { name: string }) {
return { id: '1', ...input };
}
Usage with class-validator
Apply ValidationPipe to use DTO-based validation:
import { UsePipes, ValidationPipe } from '@nestjs/common';
import { IsString, MinLength } from 'class-validator';
class CreateCatDto {
@IsString()
@MinLength(1)
name!: string;
}
@Mutation()
@UsePipes(new ValidationPipe({ whitelist: true }))
create(@Input() input: CreateCatDto) {
return { id: '1', ...input };
}
Custom Pipes
import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';
@Injectable()
export class TrimPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
if (typeof value === 'string') return value.trim();
if (typeof value === 'object' && value !== null) {
for (const key of Object.keys(value)) {
if (typeof value[key] === 'string') {
value[key] = value[key].trim();
}
}
}
return value;
}
}
@Mutation()
@UsePipes(TrimPipe)
create(@Input() input: { name: string }) {
// input.name is already trimmed
return { id: '1', ...input };
}
Global Pipes
Global pipes registered via APP_PIPE apply to all tRPC procedures:
import { APP_PIPE } from '@nestjs/core';
@Module({
providers: [
{ provide: APP_PIPE, useClass: TrimPipe },
],
})
export class AppModule {}
See the runnable example:
sample/02-enhancers-guards-pipes-filters/src/app.module.tssample/02-enhancers-guards-pipes-filters/src/common/pipes/trim.pipe.ts