nestJs 控制器

参考:

https://docs.nestjs.cn/9/controllers

控制器负责处理传入的请求和向客户端返回响应

img

控制器的目的是接收应用的特定请求。路由机制控制哪个控制器接收哪些请求。通常,每个控制器有多个路由,不同的路由可以执行不同的操作。

为了创建一个基本的控制器,我们使用类和装饰器

装饰器将类与所需的元数据相关联,并使 Nest 能够创建路由映射(将请求绑定到相应的控制器)。

创建控制器

我们先使用 nestCli 工具创建

nest g controller cats

image-20230330153112958

可以看到他是,创建了两个文件,并且更新了一个文件

我们看下他更新的这个文件,更新了什么

image-20230330153358935

可以看到增加了这些东西

至于 cats.controller.spec.ts是自动生成的单元测试样例,可要可不要

重要的是 cats.controller.ts这个文件,我们看下这个文件

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

@Controller('cats')
export class CatsController {}

可以看到就几行代码,一目了然,那后面我们创建控制器,可以采用更方便的方式

直接创建一个文件,并修改下 app.module.ts文件即可,该文件是应用模块根模块

路由

在下面的例子中

我们使用 @Controller() 装饰器定义一个基本的控制器。可选 路由路径前缀设置为 cats

@Controller() 装饰器中使用路径前缀可以使我们轻松地对一组相关的路由进行分组

并最大程度地减少重复代码。

例如

我们可以选择将一组用于管理与 /customers 下的客户实体进行互动的路由进行分组。

这样

我们可以在 @Controller() 装饰器中指定路径前缀 customers

这样就不必为文件中的每个路由重复路径的那部分。

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

// 装饰器
// 声明控制器,添加了路由组(路由前缀) cats
@Controller('cats')
export class CatsController {
  // 绑定到控制器方法, 此时路由为:/cats//customer
  @Get('/customer')
  findAll(): string {
    return 'This action returns all cats';
  }
}

此函数将返回 200 状态代码和相关的响应,在本例中只返回了一个字符串。为什么会这样? 为了解释原因,首先我们将介绍 Nest 使用两种不同的操作响应选项的概念:

标准(推荐) 使用这个内置方法,当请求处理程序返回一个 JavaScript 对象或数组时,它将自动序列化为 JSON。但是,当它返回一个 JavaScript 基本类型(例如string、number、boolean)时, Nest 将只发送值,而不尝试序列化它。这使响应处理变得简单:只需要返回值,其余的由 Nest 负责。
类库特有的 我们可以在函数签名处通过 @Res() 注入类库特定的响应对象(例如, Express)。使用此方法,你就能使用由该响应对象暴露的原生响应处理函数。例如,使用 Express,您可以使用 response.status(200).send() 构建响应

注意!Nest 检测处理程序何时使用 @Res()@Next(),表明你选择了特定于库的选项。如果在一个处理函数上同时使用了这两个方法,那么此处的标准方式就是自动禁用此路由, 你将不会得到你想要的结果。如果需要在某个处理函数上同时使用这两种方法(例如,通过注入响应对象,单独设置 cookie / header,但把其余部分留给框架),你必须在装饰器 @Res({ passthrough: true }) 中将 passthrough 选项设为 true

Request

NestJs 提供了方法参数装饰器,用来帮助我们快速获取参数 如下

装饰器 参数
@Request(),@Req() req
@Response(),@Res()* res
@Next() next
@Session() req.session
@Param(key?: string) req.params/req.params[key]
@Body(key?: string) req.body/req.body[key]
@Query(key?: string) req.query/req.query[key]
@Headers(name?: string) req.headers/req.headers[name]
@Ip() req.ip
@HostParam() req.hosts

获取get请求传参

可以使用 Request 装饰器 或者 Query 装饰器

通过Request装饰器

例:

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

// 装饰器
// 声明控制器,添加了路由组(路由前缀) cats
@Controller('cats')
export class CatsController {
  // 绑定到控制器方法, 此时路由为:/cats//customer
  @Get('/customer')
  findAll(@Request() req:any): string {
    console.log("req ===========>", req.query);
    return 'This action returns all cats';
  }
}

image-20230330175027748

image-20230330175111494

通过Query装饰器

也可以使用Query 直接获取 不需要在通过req.query 了

例:

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

// 装饰器
// 声明控制器,添加了路由组(路由前缀) cats
@Controller('cats')
export class CatsController {
  // 绑定到控制器方法, 此时路由为:/cats//customer
  @Get('/customer')
  findAll(@Query() query): string {
    console.log("query ===========>", query);
    return 'This action returns all cats';
  }
}

输出结果跟上面一致

post 获取参数

可以使用Request装饰器 或者 Body 装饰器

raw json 格式

通过Request装饰器

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

// 装饰器
// 声明控制器,添加了路由组(路由前缀) cats
@Controller('cats')
export class CatsController {
  // 绑定到控制器方法, 此时路由为:/cats//customer
  @Post('/customer')
  findAll(@Request() request): string {
    console.log("request.body ===========>", request.body);
    return 'This action returns all cats';
  }
}

image-20230331093930440

image-20230331094026587

通过Body 装饰器

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

// 装饰器
// 声明控制器,添加了路由组(路由前缀) cats
@Controller('cats')
export class CatsController {
  // 绑定到控制器方法, 此时路由为:/cats//customer
  @Post('/customer')
  findAll(@Body() body): string {
    console.log("body ===========>", body);
    return 'This action returns all cats';
  }
}

image-20230331101929610

直接读取key 也可以

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

// 装饰器
// 声明控制器,添加了路由组(路由前缀) cats
@Controller('cats')
export class CatsController {
  // 绑定到控制器方法, 此时路由为:/cats//customer
  @Post('/customer')
  findAll(@Body('name') name): string {
    console.log("name ===========>", name);
    return 'This action returns all cats';
  }
}

获取 multipart/form-data 格式 数据

如果表单数据是 multipart/form-data 格式,

那么可以使用 @UploadedFile() 装饰器来获取上传的文件。

同时,也可以使用 @Body() 装饰器来获取除文件外的表单数据。

其中,

@UseInterceptors(FileInterceptor('file')) 装饰器用于将上传的文件注入到 file 参数中,

@Body() 装饰器用于将表单数据注入到 formData 参数中。

需要注意的是,

@UseInterceptors 装饰器需要使用 @nestjs/platform-express 包中提供的 FileInterceptor 中间件,该中间件会将上传的文件保存到临时目录中,并将文件信息注入到 file 参数中。

案例

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

// 装饰器
// 声明控制器,添加了路由组(路由前缀) cats
@Controller('cats')
export class CatsController {
  // 绑定到控制器方法, 此时路由为:/cats//customer
  @Post('/customer')
  @UseInterceptors(FileInterceptor('file'))
  findAll(@UploadedFile() file: Express.Multer.File, @Body() formData): string {
    console.log("file --------->", file);
    console.log("formData --------->", formData);
    return 'This action returns all cats';
  }
}

image-20230331105434348

image-20230331105518177

命名空间“global.Express”没有已导出的成员“Multer”。

如果出现

image-20230331104954335

这个问题

这个问题通常是由于缺少依赖包 @types/multer 导致的,你可以通过以下命令安装此依赖包:

npm install --save-dev @types/multer

如果问题仍然存在,可以尝试清除缓存并重新安装依赖包:

npm cache clean --force
rm -rf node_modules
npm install

如果还是不行,可以尝试升级 @types/express 的版本,因为 @types/multer 依赖于 @types/express。你可以通过以下命令升级 @types/express

npm install --save-dev @types/express@latest

获取动态路由参数

可以使用Request装饰器 或者 Param 装饰器 跟express 完全一样

通过Request装饰器

例:

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

// 装饰器
// 声明控制器,添加了路由组(路由前缀) cats
@Controller('cats')
export class CatsController {
  // 绑定到控制器方法, 此时路由为:/cats/customer
  @Get('/customer/:id')
  findAll(@Request() req): string {
    console.log("file --------->", req);
    return 'This action returns all cats';
  }
}

请求:

http://localhost:3000/cats/customer/1314

结果

image-20230331110611953

通过 params装饰器

import { Controller, Request, Post, Body, UseInterceptors, UploadedFile, Get, Param } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';

// 装饰器
// 声明控制器,添加了路由组(路由前缀) cats
@Controller('cats')
export class CatsController {
  // 绑定到控制器方法, 此时路由为:/cats/customer
  @Get('/customer/:id')
  findAll(@Param() param): string {
    console.log("param --------->", param);
    return 'This action returns all cats';
  }
}

请求:

http://localhost:3000/cats/customer/1314

结果

image-20230331110849036

获取header 信息

@Headers() headers

例:

import { Controller, Headers, Post, Body, UseInterceptors, UploadedFile, Get, Param } from '@nestjs/common';

// 装饰器
// 声明控制器,添加了路由组(路由前缀) cats
@Controller('cats')
export class CatsController {
  // 绑定到控制器方法, 此时路由为:/cats/customer
  @Get('/customer/:id')
  findAll(@Headers() headers): string {
    console.log("headers --------->", headers);
    return 'This action returns all cats';
  }
}

image-20230331111556439

状态码

使用 HttpCode 装饰器 控制接口返回的状态码

import { Controller, Headers, Post, Body, UseInterceptors, UploadedFile, Get, Param, HttpCode } from '@nestjs/common';

// 装饰器
// 声明控制器,添加了路由组(路由前缀) cats
@Controller('cats')
export class CatsController {
  // 绑定到控制器方法, 此时路由为:/cats/customer
  @Get('/customer/')
  @HttpCode(500)
  findAll(@Headers() headers): string {
    return 'This action returns all cats';
  }
}

结果

image-20230331112010829

posted @ 2023-03-31 11:21  makalo  阅读(291)  评论(0编辑  收藏  举报