2024-03-21
NestJs
00

目录

一、什么是 Controller?
二、如何将类定义为控制器?
三、如何在类的方法上定义路由?
四、NestJS参数装饰器详细说明
二、常用的装饰器
(1)常用的方法装饰器
(2)常用的方法参数装饰器
(3)其他有用但不常用的装饰器
三、调试工具
(1)获取get请求传参
(2)post 获取参数
(3)动态路由

nestjs控制器Controller(四)

这篇文章详细介绍了在NestJS框架中如何定义控制器(Controller)以处理HTTP请求,如何通过装饰器(如@Get@Post等)定义路由来响应不同的HTTP方法,并如何使用参数装饰器(如@Body@Query@Param等)从请求中提取信息。文章通过实例代码清晰展示了这些概念的应用,帮助开发者理解和使用NestJS进行Web应用开发。

一、什么是 Controller?

什么是 Controller?语义化翻译就是 控制器,它负责处理传入的请求并将响应结果返回给客户端。

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

二、如何将类定义为控制器?

在类声明上,定义 @Controller() 装饰器,即可将该类定义为控制器,在 Nest 中,几乎所有的装饰器都是以方法形式存在的,我们通过查看 @Controller() 装饰器的源码:

bash
export function Controller(prefix?: string): ClassDecorator { const path = isUndefined(prefix) ? '/' : prefix; return (target: object) => { Reflect.defineMetadata(PATH_METADATA, path, target); }; }

可以看出,控制器装饰器有一个可选的方法参数,该参数默认值为 /,其作用就是定义当前控制器类下所有路由方法的前缀,这样以来,就可以避免我们在定义路由时出现多余的相同前缀。

现在,让我们定义一个前缀为 cats 的控制器:

bash
import { Controller } from '@nestjs/common'; @Controller('cats') export class CatsController { }

三、如何在类的方法上定义路由?

在类的方法声明上,定义 @Get()@Post()@Put()@Patch()@Delete()@Options()@Head()@All()。这些装饰器都表示各自的 HTTP 请求方法。

现在,让我们在上述的 CatsController 类中定义实际开发中常用的几种路由映射:

bash
import { Controller, Get, Post, Body, Put, Param, Delete } from '@nestjs/common'; @Controller('cats') export class CatsController { @Post() async create(@Body() createCatDto: CreateCatDto) { return 'This action adds a new cat'; } @Delete(':id') async remove(@Param('id') id) { return `This action removes a #${id} cat`; } @Put(':id') async update(@Param('id') id, @Body() updateCatDto: UpdateCatDto) { return `This action updates a #${id} cat`; } @Get(':id') async findOne(@Param('id') id) { return `This action returns a #${id} cat`; } @Get() async findAll(@Query() query) { return `This action returns all cats (limit: ${query.limit} items)`; } } // createCatDto 和 updateCatDto 可以使用类来定义其结构: export class CreateCatDto { id: number; name: string; } export class UpdateCatDto { name: string; }

在定义路由时,方法参数中,我们使用到了 @Body()@Query()@Param() 这样的参数装饰器,他们是什么意思呢?用过 express 的同学都会经常接触到:reqresnextreq.bodyreq.queryreq.params等等,诸如此类的特性,下面我们列举出,在 Nest 框架中,这些装饰器与 express 中的使用方法是如何对应的

四、NestJS参数装饰器详细说明

装饰器全称缩写对应Express对象属性描述常用请求类型应用场景示例
@Request()@Req()req获取整个请求对象。所有请求类型当需要访问请求的元数据或执行非标准操作时。
@Response()@Res()res获取响应对象。所有请求类型自定义响应,如设置特定的HTTP状态码或头部。
@Next()nest获取next函数,用于执行中间件链中的下一个函数。所有请求类型在处理请求的过程中,手动控制和调用中间件链中的下一个中间件函数。
@Query()req.query / req.query[param]获取请求的查询参数(URL中的查询字符串)。GET分页参数、搜索条件等。
@Body()req.body / req.body[param]获取请求体中的数据。POST, PUT, PATCH提交表单数据,如用户注册信息、文章内容等。
@Param()req.params / req.params[param]获取请求路径中的参数,例如在RESTful API中通过资源ID访问资源。GET, DELETE访问特定资源的详情或删除操作,如/users/
@Headers()req.headers / req.headers[param]获取请求头中的数据。所有请求类型认证(如Bearer Token)、自定义头部等。
@Session()req.session获取当前会话对象。这依赖于你的应用是否使用了会话管理。所有请求类型用户登录状态、购物车内容等会话级别的数据管理。
@Ip()req.ip获取发起请求的客户端IP地址。所有请求类型使用@Ip()装饰器可以为安全审计、定位服务或请求来源限制等场景提供客户端IP地址。
@HostParam()req.hosts获取请求的主机参数(注意:@HostParam()并非Express的标准属性,此处可能需要特别处理或自定义实现)。所有请求类型@HostParam()装饰器用于获取请求的主机名参数,常见于需要基于不同主机名或子域名提供不同逻辑处理的多租户应用场景。

Tips:Nest 底层默认使用了 express 作为 web 层的框架

注意:如果在方法参数中定义了 @Res() 或 @Next(),此时该方法的 return 语句会被阻塞,因为 return 形式的返回是 nest 标准形式,而一但使用了上述两个装饰器后,nest 不会在用标准 形式返回数据,此时必须使用 res.send / res.end / res.json 等,这种 express 特定的写法返回数据。

二、常用的装饰器

(1)常用的方法装饰器

NestJS 通过一系列方法装饰器,简化了路由的定义,使得创建RESTful API变得直观和高效。

  • @Get():定义一个处理GET请求的路由。用于获取资源。
  • @Post():定义一个处理POST请求的路由。常用于创建资源。
  • @Patch():定义一个处理PATCH请求的路由。用于对资源进行部分更新。
  • @Delete():定义一个处理DELETE请求的路由。用于删除资源。

这些装饰器通过明确的HTTP方法指示,使得API的意图和行为变得清晰易懂。

(2)常用的方法参数装饰器

方法参数装饰器用于从请求中提取信息,极大地简化了数据处理过程。

  • @Body():从请求体中提取数据,常用于处理POST和PATCH请求中的内容。
  • @Query():从URL查询字符串中提取参数,常用于过滤GET请求的结果。
  • @Param():从路由参数中提取特定的值,常用于获取资源的标识符。
  • @Request(), @Req():提取整个请求对象,使得可以访问请求的所有细节。
  • @Response(), @Res():提取响应对象,用于自定义响应的发送。

这些装饰器使得从请求中获取所需的任何信息变得非常直接和方便。

(3)其他有用但不常用的装饰器

虽然在日常开发中可能不常用,但以下装饰器在特定场景下非常有用:

  • @HttpCode():自定义响应的HTTP状态码。
  • @Header():自定义响应头。
  • @Redirect():对请求进行重定向。

这些装饰器提供了额外的控制,使得可以根据需求定制响应的行为。

三、调试工具

调试工具可以使用**postMan  ApiFox** 等

(1)获取get请求传参

可以使用**Request装饰器** 或者 **Query 装饰器**express 完全一样

https://image.myxuechao.com/NestJs/3.png

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

https://image.myxuechao.com/NestJs/4.png

bash
import { Controller, Get, Post, Body, Patch, Param, Delete, Request, Query, Headers, HttpCode } from '@nestjs/common'; import { UserService } from './user.service'; @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} // ################# 获取GET请求参数的方式 ################## /** * @description 处理GET请求,使用@Request()获取整个请求对象 * @param {*} req 请求对象 * @return {*} 返回userService的findAllWithRequest方法的结果 */ @Get('request') findAllWithRequest(@Request() req) { return this.userService.findAllWithRequest(req); } /** * @description 处理GET请求,使用@Query()获取URL查询参数 * @param {*} query 查询参数 * @return {*} 返回userService的findAllWithQuery方法的结果 */ @Get('query') findAllWithQuery(@Query() query) { return this.userService.findAllWithQuery(query); } }

(2)post 获取参数

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

https://image.myxuechao.com/NestJs/5.png

或者直接使用Body 装饰器

https://image.myxuechao.com/NestJs/6.png

bash
import { Controller, Get, Post, Body, Patch, Param, Delete, Request, Query, Headers, HttpCode } from '@nestjs/common'; import { UserService } from './user.service'; @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} @Post() create(@Body() body) { console.log('body: ', body); return { code: 200, message: 'success', data: body, }; } }

(3)动态路由

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

https://image.myxuechao.com/NestJs/7.png

或者直接使用Param 装饰器

https://image.myxuechao.com/NestJs/8.png

bash
import { Controller, Get, Post, Body, Patch, Param, Delete, Version, Request, Query } from '@nestjs/common'; import { UserService } from './user.service'; @Controller('user') export class UserController { constructor(private readonly userService: UserService) { } @Get(':id') findId (@Param() param) { console.log(param) return { code:200 } } }
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:LiuXueChao

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!