NestJS请求参数处理 #

请求参数概述 #

NestJS提供了多种装饰器来获取HTTP请求中的各种参数:

装饰器 说明 来源
@Param() 路径参数 /users/:id
@Query() 查询参数 ?page=1&limit=10
@Body() 请求体 POST/PUT请求体
@Headers() 请求头 HTTP Headers
@Cookies() Cookie HTTP Cookie
@Session() Session Express Session

路径参数 @Param() #

基本用法 #

typescript
import { Controller, Get, Param } from '@nestjs/common';

@Controller('users')
export class UsersController {
  @Get(':id')
  findOne(@Param('id') id: string) {
    return `User ID: ${id}`;
  }
}

多个路径参数 #

typescript
@Get(':userId/posts/:postId')
getUserPost(
  @Param('userId') userId: string,
  @Param('postId') postId: string,
) {
  return `User: ${userId}, Post: ${postId}`;
}

获取所有路径参数 #

typescript
@Get(':userId/posts/:postId')
getUserPost(@Param() params: { userId: string; postId: string }) {
  return params;
}

参数类型转换 #

使用管道进行类型转换:

typescript
import { ParseIntPipe } from '@nestjs/common';

@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) {
  return typeof id;  // number
}

查询参数 @Query() #

基本用法 #

typescript
import { Controller, Get, Query } from '@nestjs/common';

@Controller('users')
export class UsersController {
  @Get()
  findAll(
    @Query('page') page: string,
    @Query('limit') limit: string,
  ) {
    return `Page: ${page}, Limit: ${limit}`;
  }
}

请求示例:GET /users?page=1&limit=10

获取所有查询参数 #

typescript
@Get()
findAll(@Query() query: Record<string, string>) {
  return query;
}

使用DTO #

typescript
import { IsInt, Min, IsOptional } from 'class-validator';

export class PaginationDto {
  @IsOptional()
  @IsInt()
  @Min(1)
  page?: number = 1;

  @IsOptional()
  @IsInt()
  @Min(1)
  limit?: number = 10;
}

@Get()
findAll(@Query() pagination: PaginationDto) {
  return pagination;
}

类型转换 #

typescript
import { ParseIntPipe } from '@nestjs/common';

@Get()
findAll(
  @Query('page', new ParseIntPipe({ optional: true })) page: number = 1,
  @Query('limit', new ParseIntPipe({ optional: true })) limit: number = 10,
) {
  return { page, limit };
}

请求体 @Body() #

基本用法 #

typescript
import { Controller, Post, Body } from '@nestjs/common';

@Controller('users')
export class UsersController {
  @Post()
  create(@Body() body: any) {
    return body;
  }
}

使用DTO #

typescript
import { IsString, IsEmail, IsInt, Min } from 'class-validator';

export class CreateUserDto {
  @IsString()
  name: string;

  @IsEmail()
  email: string;

  @IsInt()
  @Min(0)
  age: number;
}

@Post()
create(@Body() createUserDto: CreateUserDto) {
  return this.usersService.create(createUserDto);
}

获取单个字段 #

typescript
@Post()
create(
  @Body('name') name: string,
  @Body('email') email: string,
) {
  return { name, email };
}

数组请求体 #

typescript
@Post('batch')
createBatch(@Body() users: CreateUserDto[]) {
  return this.usersService.createBatch(users);
}

请求头 @Headers() #

获取单个请求头 #

typescript
import { Controller, Get, Headers } from '@nestjs/common';

@Controller('users')
export class UsersController {
  @Get()
  findAll(@Headers('authorization') authorization: string) {
    return { authorization };
  }
}

获取所有请求头 #

typescript
@Get()
findAll(@Headers() headers: Record<string, string>) {
  return headers;
}

需要安装cookie-parser:

bash
npm install cookie-parser
npm install -D @types/cookie-parser

配置:

typescript
import * as cookieParser from 'cookie-parser';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(cookieParser());
  await app.listen(3000);
}

使用:

typescript
import { Controller, Get, Cookies } from '@nestjs/common';

@Controller('users')
export class UsersController {
  @Get()
  findAll(@Cookies('token') token: string) {
    return { token };
  }
}

Session @Session() #

需要安装express-session:

bash
npm install express-session
npm install -D @types/express-session

配置:

typescript
import * as session from 'express-session';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(
    session({
      secret: 'your-secret-key',
      resave: false,
      saveUninitialized: false,
    }),
  );
  await app.listen(3000);
}

使用:

typescript
import { Controller, Get, Session } from '@nestjs/common';

@Controller('users')
export class UsersController {
  @Get('profile')
  getProfile(@Session() session: Record<string, any>) {
    return session.user;
  }
}

请求对象 @Req() #

直接访问Express请求对象:

typescript
import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';

@Controller('users')
export class UsersController {
  @Get()
  findAll(@Req() request: Request) {
    return {
      url: request.url,
      method: request.method,
      headers: request.headers,
      query: request.query,
      params: request.params,
      body: request.body,
    };
  }
}

文件上传 #

单文件上传 #

typescript
import {
  Controller,
  Post,
  UseInterceptors,
  UploadedFile,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';

@Controller('upload')
export class UploadController {
  @Post()
  @UseInterceptors(FileInterceptor('file'))
  uploadFile(@UploadedFile() file: Express.Multer.File) {
    return {
      filename: file.originalname,
      size: file.size,
      mimetype: file.mimetype,
    };
  }
}

多文件上传 #

typescript
@Post('multiple')
@UseInterceptors(FilesInterceptor('files', 10))
uploadFiles(@UploadedFiles() files: Express.Multer.File[]) {
  return files.map(file => ({
    filename: file.originalname,
    size: file.size,
  }));
}

字段文件上传 #

typescript
@Post('fields')
@UseInterceptors(
  FileFieldsInterceptor([
    { name: 'avatar', maxCount: 1 },
    { name: 'documents', maxCount: 10 },
  ]),
)
uploadFileFields(
  @UploadedFiles()
  files: {
    avatar?: Express.Multer.File[];
    documents?: Express.Multer.File[];
  },
) {
  return files;
}

参数验证 #

使用class-validator #

安装依赖:

bash
npm install class-validator class-transformer

配置全局验证管道:

typescript
import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}

DTO验证示例 #

typescript
import {
  IsString,
  IsEmail,
  IsInt,
  Min,
  Max,
  IsOptional,
  IsNotEmpty,
  MinLength,
  MaxLength,
} from 'class-validator';

export class CreateUserDto {
  @IsString()
  @IsNotEmpty()
  @MinLength(2)
  @MaxLength(50)
  name: string;

  @IsEmail()
  email: string;

  @IsInt()
  @Min(0)
  @Max(150)
  age: number;

  @IsOptional()
  @IsString()
  bio?: string;
}

验证选项 #

typescript
app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,           // 过滤未定义的属性
    forbidNonWhitelisted: true, // 拒绝未定义的属性
    transform: true,           // 自动类型转换
    disableErrorMessages: false, // 显示错误信息
  }),
);

自定义参数装饰器 #

typescript
import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const CurrentUser = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    const user = request.user;

    return data ? user?.[data] : user;
  },
);

// 使用
@Get('profile')
getProfile(@CurrentUser() user: User) {
  return user;
}

@Get('email')
getEmail(@CurrentUser('email') email: string) {
  return { email };
}

总结 #

本章学习了NestJS请求参数处理:

  • 路径参数 @Param()
  • 查询参数 @Query()
  • 请求体 @Body()
  • 请求头 @Headers()
  • Cookie和Session
  • 文件上传
  • 参数验证

接下来,让我们学习 响应处理

最后更新:2026-03-28