• NestJS学习:搭建项目、依赖注入、常用命令、RESTful 风格设计


    介绍

    Nest (NestJS) 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的开发框架。它利用 JavaScript 的渐进增强的能力,使用并完全支持 TypeScript (仍然允许开发者使用纯 JavaScript 进行开发),并结合了 OOP (面向对象编程)、FP (函数式编程)和 FRP (函数响应式编程)。

    在底层,Nest 构建在强大的 HTTP 服务器框架上,例如 Express (默认),并且还可以通过配置从而使用 Fastify !

    Nest 在这些常见的 Node.js 框架 (Express/Fastify) 之上提高了一个抽象级别,但仍然向开发者直接暴露了底层框架的 API。这使得开发者可以自由地使用适用于底层平台的无数的第三方模块。

    Nest.js:是“Angular 的服务端实现”,基于装饰器。会有很多angular的开发风格。

    中文网址:https://docs.nestjs.cn/

    参考:B站视频教程

    作者也是csdn的大佬,博客地址是:小满zs

    项目搭建

    创建项目

    //安装脚手架
    npm i -g @nestjs/cli
    /创建项目
    nest new project-name
    
    • 1
    • 2
    • 3
    • 4

    将会创建 project-name 目录, 安装 node_modules 和一些其他样板文件,并将创建一个 src 目录,目录中包含几个核心文件。

    src
     ├── app.controller.spec.ts
     ├── app.controller.ts
     ├── app.module.ts
     ├── app.service.ts
     └── main.ts
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    app.controller.ts 带有单个路由的基本控制器示例,用于编写路由
    app.controller.spec.ts 对于基本控制器的单元测试样例
    app.module.ts 应用程序的根模块。
    app.service.ts 带有单个方法的基本服务,主要编写接口返回什么数据。
    main.ts 应用程序入口文件。它使用 NestFactory 用来创建 Nest 应用实例。类似于vue的main.ts

    main.ts 包含一个异步函数,它负责引导我们的应用程序:

    /* main.ts */
    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      await app.listen(3000);
    }
    bootstrap();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    要创建一个 Nest 应用实例,我们使用了 NestFactory 核心类。NestFactory 暴露了一些静态方法用于创建应用实例。 create() 方法返回一个实现 INestApplication 接口的对象。该对象提供了一组可用的方法

    请注意,使用 Nest CLI 搭建的项目会创建一个初始项目结构,我们鼓励开发人员将每个模块保存在自己的专用目录中。

    启动

    $ npm run start
    
    • 1

    此命令启动 HTTP 服务监听定义在 src/main.ts 文件中定义的端口号。在应用程序运行后, 打开浏览器并访问 http://localhost:3000/。 你应该看到 Hello world! 信息。
    在这里插入图片描述
    遇到的问题
    发现eslint老是报下面的这个错误
    在这里插入图片描述
    查了一下是由于行尾风格配置导致,解决方法,在.prettierrc 文件中添加如下代码

     "endOfLine": "auto"
    
    • 1

    按快捷键:ctrl + shift + p,选择重启eslint

    在这里插入图片描述

    依赖注入

    未使用控制反转和依赖注入之前的代码

    class A {
      name: string;
      constructor(name: string) {
        this.name = name;
      }
    }
    
    class B {
      age: number;
      entity: A;
      constructor(age: number) {
        this.age = age;
        this.entity = new A('张三');
      }
    }
    
    const c = new B(15);
    
    c.entity.name;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    B 中代码的实现是需要依赖 A 的,两者的代码耦合度非常高。当两者之间的业务逻辑复杂程度增加的情况下,维护成本与代码可读性都会随着增加,并且很难再多引入额外的模块进行功能拓展。

    为了解决这个问题可以使用IOC容器

    class A {
      name: string;
      constructor(name: string) {
        this.name = name;
      }
    }
    
    //中间件用于解耦
    class Container {
      modeuls: any;
      constructor() {
        this.modeuls = {};
      }
      provide(key: string, modeuls: any) {
        this.modeuls[key] = modeuls;
      }
      get(key) {
        return this.modeuls[key];
      }
    }
    
    class B {
      a: any;
    
      constructor(container: Container) {
        this.a = container.get('a');
      }
    }
    
    const mo = new Container();
    mo.provide('a', new A('张三'));
    const c = new B(mo);
    
    c.a;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    本质上就是写了一个中间件,来收集依赖,主要是为了解耦,减少维护成本

    常用命令

    nest --help 可以查看nestjs所有的命令
    在这里插入图片描述
    Nest.js:是“Angular 的服务端实现”,基于装饰器。两种直接命令也是很相似的。

    生成controller.ts

    nest g co 名称
    
    • 1

    会自动生成文件,并将文件添加到app.module.ts
    在这里插入图片描述

    生成 module.ts

    nest g mo 模块名
    
    • 1

    创建的模块会自动添加到app.module.ts里的imports数组里
    在这里插入图片描述

    生成service.ts

    nest g s 服务名
    
    • 1

    生成CURD模板

     nest g resource 名称
    
    • 1

    第一次使用这个命令的时候,除了生成文件之外还会自动使用 npm 帮我们更新资源,安装一些额外的插件,后续再次使用就不会更新了。
    大多少情况选择第一个即可
    在这里插入图片描述
    会自动生成文件和基础代码,方便快速开发
    在这里插入图片描述
    在这里插入图片描述

    RESTful 风格设计

    RESTful 是一种风格,在RESTful中,一切都被认为是资源,每个资源有对应的URL标识.。

    接口URL

    传统接口是?后面跟参数的格式,比如:http://localhost:8080/api/get_list?id=1 。RESTful风格使用/来代替了?,比如:http://localhost:8080/api/get_list/1

    RESTful 风格一个接口就会完成 增删改差 他是通过不同的请求方式来区分的

    • 查询GET
    • 提交POST
    • 更新 PUT PATCH
    • 删除 DELETE

    在这里插入图片描述
    比如直接请求http://localhost:5000/user,执行的是@Get()
    在这里插入图片描述
    请求http://localhost:5000/user/1,执行的是@Get(':id')
    在这里插入图片描述
    nest会根据路由自动进行匹配。

    RESTful 版本控制

    一共有三种我们一般用第一种 更加语义化。常用在新切分支,对代码进行改动时使用。

    URI Versioning版本将在请求的 URI 中传递(默认)
    Header Versioning自定义请求标头将指定版本
    Media Type Versioning请求的Accept标头将指定版本

    main.ts

    import { NestFactory } from '@nestjs/core';
    import { VersioningType } from '@nestjs/common';
    import { AppModule } from './app.module';
     
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      app.enableVersioning({
        type: VersioningType.URI,
      })
      await app.listen(3000);
    }
    bootstrap();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    controller文件

    @Controller({
      path: 'user',
      version: '2',
    })
    
    • 1
    • 2
    • 3
    • 4

    设置之后请求的url必须要添加版本,否则会404
    在这里插入图片描述
    在这里插入图片描述
    如果只是单独修改某几个接口,就不要直接修改Controller 装饰器,只需要单独修改某一个请求就好了。版本控制只会在添加了装饰器的接口生效

    @Controller('user')
    export class UserController {
      constructor(private readonly userService: UserService) { }
    
      @Post()
      create(@Body() createUserDto: CreateUserDto) {
        return this.userService.create(createUserDto);
      }
    
      @Get()
      @Version('2')
      findAll() {
        return this.userService.findAll();
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述
    没添加版本装饰器
    在这里插入图片描述

    注意:比如你的版本是2,那么访问时是v2;如果你的版本写的是v2,访问时就必须是vv2

  • 相关阅读:
    day38
    在执行对 HDFS 中创建用户目录的指令时,回复的命令如下图所示
    FPGA Zynq MPSOC ZU5EV 下CAN 应用编程
    Linux 操作系统启动流程1
    关于两种常用特殊字符判断方法
    Apifox vs Eolink,国内 Api 工具哪家强?
    k8s Helm安装EFK
    06 nginx 处理转发其他域的处理 以及 proxy_redirect
    【产品设计】B端SaaS产品原则
    B2B营销新策略 | B2B企业如何实现产品导向增长目标(附方案下载)
  • 原文地址:https://blog.csdn.net/weixin_41897680/article/details/127947844