NestJS控制器(Controller) #

什么是控制器? #

控制器负责处理传入的HTTP请求,并将响应返回给客户端。控制器使用@Controller()装饰器来定义,其中的方法使用路由装饰器(如@Get()@Post()等)来指定处理哪些请求。

基本控制器 #

创建控制器 #

使用CLI创建控制器:

bash
nest g controller users

生成的代码:

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

@Controller('users')
export class UsersController {}

路由前缀 #

@Controller()装饰器接收一个可选的路由前缀:

typescript
@Controller('users')
export class UsersController {
  // 所有路由都以 /users 开头
}

路由方法 #

HTTP方法装饰器 #

typescript
import { Controller, Get, Post, Put, Patch, Delete } from '@nestjs/common';

@Controller('users')
export class UsersController {
  @Get()
  findAll(): string {
    return 'This action returns all users';
  }

  @Get(':id')
  findOne(@Param('id') id: string): string {
    return `This action returns user #${id}`;
  }

  @Post()
  create(): string {
    return 'This action adds a new user';
  }

  @Put(':id')
  update(@Param('id') id: string): string {
    return `This action updates user #${id}`;
  }

  @Patch(':id')
  partialUpdate(@Param('id') id: string): string {
    return `This action partially updates user #${id}`;
  }

  @Delete(':id')
  remove(@Param('id') id: string): string {
    return `This action removes user #${id}`;
  }
}

路由装饰器对照表 #

装饰器 HTTP方法 示例路由
@Get() GET /users
@Post() POST /users
@Put() PUT /users/:id
@Patch() PATCH /users/:id
@Delete() DELETE /users/:id
@All() 所有方法 /users

路由路径 #

路由装饰器可以指定额外的路径:

typescript
@Controller('users')
export class UsersController {
  @Get()                    // GET /users
  findAll() {}

  @Get('profile')           // GET /users/profile
  getProfile() {}

  @Get('admin/all')         // GET /users/admin/all
  findAllAdmin() {}
}

请求参数 #

@Req() 获取请求对象 #

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

@Controller('users')
export class UsersController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all users';
  }
}

@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}`;
  }

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

  @Get(':id')
  findOneAllParams(@Param() params: { id: string }) {
    return `User ID: ${params.id}`;
  }
}

@Query() 查询参数 #

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

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

  @Get('search')
  search(@Query() query: { keyword: string; page?: number }) {
    return `Searching for: ${query.keyword}`;
  }
}

@Body() 请求体 #

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

@Controller('users')
export class UsersController {
  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Post('profile')
  updateProfile(
    @Body('name') name: string,
    @Body('email') email: string,
  ) {
    return { name, email };
  }
}

@Headers() 请求头 #

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

@Controller('users')
export class UsersController {
  @Get()
  findAll(
    @Headers('authorization') authorization: string,
    @Headers() headers: Record<string, string>,
  ) {
    return { authorization, headers };
  }
}

@Ip() 客户端IP #

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

@Controller('users')
export class UsersController {
  @Get()
  findAll(@Ip() ip: string) {
    return `Request from IP: ${ip}`;
  }
}

请求装饰器汇总 #

装饰器 说明
@Req() 请求对象
@Res() 响应对象
@Param() 路径参数
@Query() 查询参数
@Body() 请求体
@Headers() 请求头
@Ip() 客户端IP
@Session() Session对象
@HostParam() Host参数

响应处理 #

默认响应 #

NestJS自动将返回值序列化为JSON:

typescript
@Get()
findAll() {
  return { message: 'Success', data: [] };
}
// 响应: {"message":"Success","data":[]}

使用@Res()自定义响应 #

typescript
import { Controller, Get, Res } from '@nestjs/common';
import { Response } from 'express';

@Controller('users')
export class UsersController {
  @Get()
  findAll(@Res() response: Response) {
    response.status(200).json({
      message: 'Success',
      data: [],
    });
  }
}

注意: 使用@Res()后,需要手动调用response.json()等方法,否则请求会挂起。

设置状态码 #

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

@Controller('users')
export class UsersController {
  @Post()
  @HttpCode(HttpStatus.CREATED)  // 201
  create() {
    return 'User created';
  }

  @Post('login')
  @HttpCode(HttpStatus.OK)  // 200
  login() {
    return 'Login successful';
  }
}

设置响应头 #

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

@Controller('users')
export class UsersController {
  @Get()
  @Header('Cache-Control', 'none')
  @Header('X-Custom-Header', 'value')
  findAll() {
    return 'This action returns all users';
  }
}

重定向 #

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

@Controller('users')
export class UsersController {
  @Get('docs')
  @Redirect('https://docs.nestjs.com', 302)
  getDocs() {}

  @Get('redirect')
  @Redirect()
  redirectTo() {
    return {
      url: 'https://nestjs.com',
      statusCode: 301,
    };
  }
}

异步处理 #

控制器方法支持异步操作:

使用Promise #

typescript
@Get()
async findAll(): Promise<any[]> {
  return await this.usersService.findAll();
}

使用RxJS Observable #

typescript
import { Observable, of } from 'rxjs';

@Get()
findAll(): Observable<any[]> {
  return of([]);
}

资源路由示例 #

完整的CRUD控制器示例:

typescript
import {
  Controller,
  Get,
  Post,
  Put,
  Patch,
  Delete,
  Body,
  Param,
  ParseIntPipe,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id', ParseIntPipe) id: number) {
    return this.usersService.findOne(id);
  }

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

  @Put(':id')
  update(
    @Param('id', ParseIntPipe) id: number,
    @Body() updateUserDto: UpdateUserDto,
  ) {
    return this.usersService.update(id, updateUserDto);
  }

  @Patch(':id')
  partialUpdate(
    @Param('id', ParseIntPipe) id: number,
    @Body() updateUserDto: UpdateUserDto,
  ) {
    return this.usersService.partialUpdate(id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id', ParseIntPipe) id: number) {
    return this.usersService.remove(id);
  }
}

控制器注册 #

控制器需要在模块中注册:

typescript
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}

作用域 #

控制器默认是单例模式,可以配置不同的作用域:

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

@Controller({ path: 'users', scope: Scope.REQUEST })
export class UsersController {}
作用域 说明
DEFAULT 单例模式(默认)
REQUEST 每个请求创建新实例
TRANSIENT 每次注入创建新实例

总结 #

本章深入学习了NestJS控制器:

  • 控制器的定义和路由前缀
  • HTTP方法装饰器的使用
  • 各种请求参数的获取
  • 响应处理方式
  • 异步操作支持

接下来,让我们学习 提供者(Provider)

最后更新:2026-03-28