likes
comments
collection

NestJs快速入门

作者站长头像
站长
· 阅读数 14

介绍nestjs

NestJs 是一个渐进的 Node.js 框架,可以在 TypeScript 和 JavaScript (ES6、ES7、ES8)之上构建高效、可伸缩的企业级服务器端应用程序。

NestJs 基于 TypeScript 编写并且结合了 OOP(面向对象编程),FP(函数式编程)和 FRP (函数式响应编程)的相关理念。在设计上的很多灵感来自于 Angular,Angular 的很多模式又来自于 Java 中的 Spring 框架,依赖注入、面向切面编程等,所以我们也可以认为: NestJs 是 Node.js 版的 Spring 框架。

NestJs 框架底层 HTTP 平台默认是基于 Express 实现的,所以无需担心第三方库的缺失。 NestJs 旨在成为一个与平台无关的框架。 通过平台,可以创建可重用的逻辑部件,开发人员可以利用这些部件来跨越多种不同类型的应用程序。 从技术上讲,NestJs 可以在创建适配器后使用任何 Node HTTP 框架。 有两个支持开箱即用的 HTTP 平台:express 和 fastify。 您可以选择最适合您需求的产品。

NestJs 的核心思想:就是提供了一个层与层直接的耦合度极小,抽象化极高的一个架构体系。

NestJs脚手架及常用命令

  • 安装:npm i -g @nestjs/cli 或者 cnpm i -g @nestjs/cli 或者 yarn global add @nestjs/cli
  • 创建:nest new project-name
  • 相关命令:
    • nest new 名称 创建项目
    • nest -h/--help 帮助
    • nest g co 名称 创建控制器
    • nest g s 名称 创建服务
    • nest g mi 名称 创建中间件
    • nest g pi 名称 创建管道
    • nest g mo 名称 创建模块
    • nest g gu 名称 创建守卫
  • 凡是以脚手架创建的模块,控制器等等都会自动添加到对应配置位置,不需要手动配置

概述

控制器

  • NestJs 中的控制器层负责处理传入的请求, 并返回对客户端的响应。
  • NestJs 能够创建路由映射,Controller将请求绑定到相应的控制器。
  • NestJs 也提供了其他 HTTP 请求方法的装饰器 @Put() 、@Delete()、@Patch()、 @Options()、 @Head()和 @All()
  • 在 NestJs 中获取 Get 传值或者 Post 提交的数据的话我们可以使用 Nestjs 中的装饰器@Query()和@Body()来获取

NestJs快速入门

提供者

NestJs 中的提供者负责逻辑处理和与数据层打交道。他们通过 constructor注入依赖关系提供者是以@Injectable() 装饰器注解的类。

NestJs快速入门

NestJs快速入门

NestJs快速入门

模块

NestJs 中的模块是具有 @Module() 装饰器的类。 @Module() 装饰器提供了元数据,Nest 用它来组织应用程序结构。

NestJs快速入门

NestJs快速入门

NestJs快速入门

因为上面根模块 App.modules 已经引入过该模块,所以其他模块就可以直接使用user模块的Service

NestJs快速入门

中间件

中间件就是匹配路由之前或者匹配路由完成做的一系列的操作。中间件中如果想往下匹配的话,使用 next()

中间件的任务:

  • 执行任何代码
  • 对请求和响应对象进行更改
  • 结束请求-响应周期
  • 调用堆栈中的下一个中间件函数
  • 如果当前的中间件函数没有结束请求-响应周期, 它必须调用 next() 将控制传递给下一个中间 件函数。否则, 请求将被挂起

异常过滤器

内置的异常层负责处理整个应用程序中的所有抛出的异常。当捕获到未处理的异常时,最终用户将收到友好的响应

NestJs快速入门

管道

NestJs 中的管道可以将输入数据转换为所需的输出。此外,它也可以处理验证, 当数据不正确时可能会抛出异常。具有 @Injectable() 装饰器的类。管道需要实现 PipeTransform 接口。

NestJs快速入门

守卫

守卫是一个使用 @Injectable() 装饰器的类。守卫应该实现 CanActivate 接口

守卫有一个单独的责任。它们确定请求是否应该由路由处理程序处理。到目前为止,访问限制逻辑大多在中间件内。这样很好,因为诸如 token 验证或将 request 对象附加属性与特定路由没有强关联。但中间件是非常笨的。它不知道调用 next() 函数后会执行哪个处理程序。另一方面,守卫可以访问 ExecutionContext 对象,所以我们确切知道将要执行什么

简单的说就是在 Nextjs 中如果我们想做权限判断的话可以在守卫中完成,也可以在中间件中完成,但是一般通过守卫最好

NestJs快速入门

拦截器

拦截器具有一系列有用的功能,这些功能受面向切面编程(AOP)技术的启发。它们可以:

  • 在函数执行之前/之后绑定额外的逻辑
  • 转换从函数返回的结果
  • 转换从函数抛出的异常
  • 扩展基本函数行为
  • 根据所选条件完全重写函数 (例如, 缓存目的)

NestJs快速入门

NestJs的执行链路

客户端请求-->中间件-->守卫 -->拦截器之前 -->管道--> 控制器处理并响应-->拦截器之后-->过滤器

  1. 接收客户端发起请求
  2. 中间件去做请求处理,比如helmet,csrf,rate limiting,compression等等常用的处理请求的中间件
  3. 守卫就验证该用户的身份,如果没有权限或者没有登录,就直接抛出异常,最适合做权限管理
  4. 拦截器根据文档的解释,拦截器之前不能修改请求信息。只能获取请求信息
  5. 管道做请求的数据验证和转化,如果验证失败抛出异常
  6. 这里处理响应请求的业务,俗称controller,处理请求和服务桥梁,直接响应服务处理结果
  7. 拦截器之后只能修改响应body数据
  8. 最后走过滤器:如果前面任何位置发生抛出异常操作,都会直接走它

总结

NestJs很多提供的内部功能,看似功能重复,但是实际上有明确的职责划分,按照约定来,能使结构清晰,代码更好维护

  • 模块是按业务逻辑划分基本单元,包含控制器和服务。控制器是处理请求和响应数据的部件,服务处理实际业务逻辑的部件
  • 中间件是路由处理Handler前的数据处理层,只能在模块或者全局注册,可以做日志处理中间件、用户认证中间件等处理,中间件和express的中间件一样,所以可以访问整个request、response的上下文,模块作用域可以依赖注入服务。全局注册只能是一个纯函数或者一个高阶函数
  • 管道是数据流处理,在中间件后路由处理前做数据处理,可以控制器中的类、方法、方法参数、全局注册使用,只能是一个纯函数。可以做数据验证,数据转换等数据处理
  • 守卫是决定请求是否可以到达对应的路由处理器,能够知道当前路由的执行上下文,可以控制器中的类、方法、全局注册使用,可以做角色守卫
  • 拦截器是进入控制器之前和之后处理相关逻辑,能够知道当前路由的执行上下文,可以控制器中的类、方法、全局注册使用,可以做日志、事务处理、异常处理、响应数据格式等
  • 过滤器是捕获错误信息,返回响应给客户端。可以控制器中的类、方法、全局注册使用,可以做自定义响应异常格式
  • 中间件、过滤器、管道、守卫、拦截器,这是几个比较容易混淆的东西。他们有个共同点都是和控制器挂钩的 东西。他们有个共同点都是和控制器挂钩的中间抽象处理层,但是他们的职责却不一样