NestJS - controllers总结

459 阅读3分钟

控制器简介

控制器(Controller)是MVC架构中C的实现,它负责接收请求(Requests)和发出响应(Responses)。

Capture-2023-10-26-150602.png

控制器代码:

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto): string {
    console.log(createCatDto);
    return 'This action adds a new cat';
  }

  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}

Module中引入:

@Module({
  imports: [],
  controllers: [AppController, CatsController],
  providers: [AppService],
})
export class AppModule {}

核心要点

1. 创建Controller

  • 控制器是通过 @Controller() 装饰器来定义。
  • @Controller() 中指定路由路径前缀
  • 可以使用cli命令创建控制器nest g controller [name]

Controller 装饰器源码:

截屏2023-12-28 16.07.00.png

2. 路由映射

通过在控制器的方法前使用HTTP请求方法装饰器(例如 @Get() ),Nest创建特定于HTTP请求方法和路由路径的处理程序。

@Get()
findAll(): string {
  return 'This action returns all cats';
}

Nest 为所有标准 HTTP 方法提供了装饰器: @Get() @Post() @Put() @Delete() @Patch() @Options() 和 @Head()  @All()

方法装饰器 的源码:

截屏2023-12-28 16.10.04.png

3. 路由可以使用通配符:

@Get('ab*cd')
findAll() {
  return 'This route uses a wildcard';
}

4. 请求对象

  • 通过 @Req() 装饰器注入请求对象,以访问请求详情。
  • 要获取请求对象的参数只需要使用装饰器,如 @Body()@Query()@Param()@Headers() 等。

截屏2023-12-28 16.10.04.png

响应流程

Nest提供两种响应操作方式:标准(推荐)和库特定方式。

  1. Standard

    • 当请求处理程序返回 JavaScript 对象或数组时,它将自动序列化为 JSON。但是,当它返回 JavaScript 基元类型(例如, string 、 number 、 boolean )时,Nest 将只发送该值而不尝试序列化它。这使得响应处理变得简单:只需返回值,Nest 负责其余的工作。
    • 默认响应状态码是200,POST请求默认为201,可以通过 @HttpCode(...) 装饰器修改。
  2. Library-specific

    • Nest 检测处理程序使用 @Res() 或 @Next() 时,会禁用标准方法。通过此方法获取响应对象,使用该对象公开的处理方法。例如,使用 Express,您可以使用类似 response.status(200).send() .
    • 同时使用标准方式和库特定方式会导致标准方式自动禁用,除非设置 @Res() 装饰器的 passthrough 选项为 true

其他操作

1. 指定状态码

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}

⚠️ Nest提供了一个 HttpStatus 枚举:ttpStatus.CREATEDHttpStatus.OK

HttpCode装饰器源码:

截屏2023-12-28 15.39.48.png

2. 设置header

@Post()
@Header('Cache-Control', 'none')
create() {
  return 'This action adds a new cat';
}

⚠️注意:区分HeadersHeader 两个装饰器

3. 重定向

@Get()
@Redirect('<https://nestjs.com>', 301)
create() {
  return 'This action adds a new cat';
}

@Redirect() 接受两个参数, url 并且 statusCode 都是可选的。如果省略,则默认值 statusCode 为 302

📌 动态重定向

返回一个对象,返回的值将覆盖传递给 @Redirect() 装饰器的参数

@Get('docs')
@Redirect('<https://docs.nestjs.com>', 302)
getDocs(@Query('version') version) {
  if (version && version === '5') {
    return { url: '<https://docs.nestjs.com/v5/>' };
  }
}

示例

import {
  Controller,
  Get,
  Post,
  Param,
  Body,
  Put,
  Delete,
  HttpCode,
  Header,
  Headers,
  Redirect,
  Query,
  Req,
  Res,
} from '@nestjs/common';
import { CreateCatDto, UpdateCatDto } from './dot';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto): string {
    console.log(createCatDto);
    return 'This action adds a new cat';
  }

  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }

  @Get(':id/:name')
  findOne1(@Param() params: any): string {
    console.log(params);
    return `This action returns a #${params.name} cat`;
  }

  @Get('req')
  findOne2(@Req() req: any): string {
    console.log(req);
    return `get req`;
  }

  @Get('res')
  findOne3(@Res() response: any): string {
    // @Res({ passthrough: true })
    console.log(response);
    response.status(404).send('res');
    return `get res`;
  }

  @Put(':id')
  update(@Param() id: string, @Body() updateCatDto: UpdateCatDto): string {
    console.log(updateCatDto);
    return `This action updates a #${id} cat`;
  }

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

  @Get('ab*cd')
  find(): string {
    return 'This route uses a wildcard';
  }

  @Post('status')
  @HttpCode(204)
  create1() {
    return 'This action adds a new cat';
  }

  @Post('setHeader')
  @Header('Cache-Control', 'none')
  m1() {
    return 'This action adds a new cat';
  }

  @Get('redirect')
  @Redirect('<https://www.baidu.com>', 301)
  redirect(@Query('version') version: string) {
    if (version && version === '5') {
      return { url: '<https://www.xiaomi.com>' };
    }
    return 'This action returns all cats';
  }

  @Get('Headers')
  find1(@Headers() header: any): string {
    console.log(header);
    return 'This route uses a wildcard';
  }

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