首页 > 其他分享 >Nest快速上手

Nest快速上手

时间:2024-07-10 16:02:26浏览次数:6  
标签:AppService app AppController user 模块 快速 Nest NestJS

快速创建

在学习 NestJS 之前请先确保操作系统中安装过 Node.js(版本 >= 16)

本篇文章使用的Node.js版本是16.19.0。

使用 Nest 命令行接口 设置新项目非常简单。安装 npm 后,你可以在操作系统终端中使用以下命令创建一个新的 Nest 项目:

$ npm i -g @nestjs/cli
$ nest new nest-study

创建项目时,要求你选择包管理工具(npm,yarn,pnpm),本篇文章选择的是 npm 作为包管理工具。

然后使用npm run start命令运行项目,项目的默认端口是3000。可以使用 进行访问。

http://localhost:3000
还可以使用 npm run start:dev 命令运行项目,此命令将监视你的文件,自动重新编译并重新加载服务器。

基本概念

运行起来后,来分析项目目录核心结构,重点关注 src 文件夹里的内容。

文件名描述
app.controller.spec.ts具有单一路由的基本控制器
app.controller.ts控制器的单元测试
app.module.ts应用的根模块
app.service.ts具有单一方法的基本服务
main.ts使用核心函数 NestFactory 创建 Nest 应用实例的应用入口文件

首先从入口文件 main.ts 开始介绍。

// 引入 NestJS 的 NestFactory 类,用于创建 NestJS 应用程序的实例 
import { NestFactory } from '@nestjs/core';
// 引入应用的主模块,它是 NestJS 应用程序的根模块
import { AppModule } from './app.module';

// 定义一个异步的 bootstrap 函数,用于启动 NestJS 应用程序 
async function bootstrap() {
  // 使用 NestFactory 的 create 方法创建 NestJS 应用程序的实例,传入应用的主模块 AppModule
  const app = await NestFactory.create(AppModule);
  // 调用 app 实例的 listen 方法,启动 HTTP 服务器并监听 3000 端口  
  // 注意:listen 方法也是异步的,因此使用 await 等待其完成
  await app.listen(3000);
}
// 调用 bootstrap 函数启动 NestJS 应用程序 
bootstrap();

要创建 Nest 应用实例,就需要使用到核心 NestFactory 类。使用它的create() 方法返回一个应用对象,通过调用这个实例的 listen() 方法,启动了一个 HTTP 服务器并让它监听在 3000 端口上。

接下来看 ./app.module.ts 文件中的内容。

// 引入 NestJS 的 Module 装饰器,用于定义 NestJS 的模块  
import { Module } from '@nestjs/common';  
// 引入当前应用中定义的 AppController 类,它负责处理进入的 HTTP 请求  
import { AppController } from './app.controller';  
// 引入当前应用中定义的 AppService 类,它封装了应用中的业务逻辑  
import { AppService } from './app.service';  
  
// 使用 @Module 装饰器来定义一个模块,这里是根模块 AppModule  
@Module({  
  // imports 数组用于导入其他模块,以便在当前模块中使用它们的功能  
  // 在这个例子中,根模块没有导入其他模块,所以数组为空  
  imports: [],  
  // controllers 数组列出了当前模块中所有的控制器类  
  // 这里只列出了 AppController,因为它是处理 HTTP 请求的类  
  controllers: [AppController],  
  // providers 数组列出了当前模块中所有的服务提供者  
  // 这些服务提供者可以是任何值或类,但通常它们封装了应用的业务逻辑  
  // 在这个例子中,只列出了 AppService,它可能包含了一些与数据库交互、处理业务逻辑等功能的方法  
  providers: [AppService],  
})  
// 导出 AppModule 类,使其可以在其他模块中被导入  
export class AppModule {}

在这个 AppModule 类中,我们使用 @Module 装饰器来定义了一个 NestJS 模块。这个模块是应用的根模块,它包含了应用所需的控制器(AppController)和服务提供者(AppService)。imports 数组用于导入其他模块,但在这个例子中它是空的,因为根模块不需要导入其他模块。controllers 数组列出了所有控制器类,这些类负责处理进入的 HTTP 请求。providers 数组列出了所有服务提供者,这些服务提供者可以是任何值或类,但在这个例子中,它只包含了一个服务类 AppService,这个类可能封装了应用的业务逻辑。

然后来看 app.controller.ts 文件中的内容

// 引入 NestJS 的 Controller 和 Get 装饰器,用于定义路由处理器  
import { Controller, Get } from '@nestjs/common';  
// 引入 AppService 类,它可能封装了应用的业务逻辑,包括返回问候语的方法  
import { AppService } from './app.service';  
  
// 使用 @Controller 装饰器定义一个控制器类 AppController  
// 由于没有指定任何路由路径,这个控制器将处理根路径 '/' 的请求  
@Controller()  
export class AppController {  
  // 在构造函数中,通过依赖注入的方式获取 AppService 的实例  
  // private readonly appService: AppService 表示这是一个只读属性,其值将在构造函数中初始化  
  constructor(private readonly appService: AppService) {}  
  
  // 使用 @Get 装饰器定义一个路由处理器方法 getHello  
  // 这个方法将处理 GET 请求,并且由于它没有被指定任何路由路径,它将处理根路径 '/' 的 GET 请求  
  @Get()  
  getHello(): string {  
    // 调用 AppService 的 getHello 方法获取问候语,并返回这个问候语  
    return this.appService.getHello();  
  }  
}

在这个 AppController 类中,我们定义了一个路由处理器方法 getHello,它使用 @Get() 装饰器来指定这个方法将处理对根路径 / 的 GET 请求。方法内部,我们通过调用 AppServicegetHello 方法来获取一个问候语字符串,并将这个字符串返回给客户端。通过这种方式,NestJS 的控制器负责处理 HTTP 请求,并将业务逻辑委托给服务提供者(在这个例子中是 AppService)。

然后来看 app.service.ts 文件中的内容。

// 引入 NestJS 的 Injectable 装饰器,用于标记一个类为可注入的服务提供者  
import { Injectable } from '@nestjs/common';  
  
// 使用 @Injectable 装饰器标记 AppService 类为可注入的服务提供者  
@Injectable()  
export class AppService {  
  // 定义一个名为 getHello 的方法,该方法没有接收任何参数  
  // 方法返回一个字符串 'Hello World!',这个字符串可以被视为一个简单的问候语  
  getHello(): string {  
    return 'Hello World!';  
  }  
}

在这个 AppService 类中,我们使用 @Injectable() 装饰器来标记这个类是一个可注入的服务提供者。这意味着 NestJS 的依赖注入系统可以创建这个类的实例,并将其注入到需要它的地方,比如控制器中。getHello 方法是一个简单的示例,它返回了一个固定的字符串 'Hello World!',但在实际应用中,这个方法可能会包含更复杂的逻辑,比如从数据库中查询数据、调用其他服务或执行其他业务逻辑。

再来看 app.controller.spec.ts 文件里的内容。

// 引入 NestJS 测试模块的相关类和装饰器  
import { Test, TestingModule } from '@nestjs/testing';  
// 引入被测试的控制器类 AppController  
import { AppController } from './app.controller';  
// 引入被控制器依赖的服务类 AppService  
import { AppService } from './app.service';  
  
// 使用 describe 定义一个测试套件,用于测试 AppController  
describe('AppController', () => {  
  // 声明一个变量 appController,用于存储 AppController 的实例  
  let appController: AppController;  
  
  // 使用 beforeEach 钩子函数在每个测试用例执行之前运行  
  // 它将创建一个测试模块,并编译它,然后从中获取 AppController 的实例  
  beforeEach(async () => {  
    // 使用 Test.createTestingModule 方法创建一个测试模块  
    // 传入一个对象,指定控制器数组(包含 AppController)和服务提供者数组(包含 AppService)  
    const app: TestingModule = await Test.createTestingModule({  
      controllers: [AppController], // 指定测试模块中要包含的控制器  
      providers: [AppService], // 指定测试模块中要包含的服务提供者  
    }).compile(); // 编译测试模块  
  
    // 使用 app.get 方法从测试模块中获取 AppController 的实例  
    // 并将其赋值给之前声明的 appController 变量  
    appController = app.get<AppController>(AppController);  
  });  
  
  // 使用 describe 定义一个子测试套件,用于测试根路由('/')的 GET 请求  
  describe('root', () => {  
    // 使用 it 定义一个测试用例,测试 getHello 方法是否返回 "Hello World!"  
    it('should return "Hello World!"', () => {  
      // 调用 appController 实例的 getHello 方法,并使用 expect 断言其返回值是否为 'Hello World!'  
      expect(appController.getHello()).toBe('Hello World!');  
    });  
  });  
});

在这个文件中使用 Jest(NestJS 默认使用的测试框架)编写了单元测试示例,用于测试 AppController 类的 getHello 方法。它使用了 NestJS 提供的测试工具来创建一个测试模块,该模块包含了 AppController 和它依赖的 AppService。然后,它编译这个测试模块,并从中获取 AppController 的实例,最后通过调用 getHello 方法并断言其返回值来验证 AppController 的行为是否符合预期。

Nest基本命令

NestJS 提供了一套丰富的命令来帮助开发者快速搭建和管理项目,这些命令主要通过 Nest CLI(Nest 命令行接口)来执行。

以下是一些常用的 NestJS 命令:

名称别名描述
newn搭建新的标准模式应用程序,其中包含运行所需的所有样板文件
generateg基于原理图生成和/或修改文件
build将应用程序或工作区编译为输出文件夹
start编译并运行应用程序(或工作区中的默认项目)
add编译并运行应用程序(或工作区中的默认项目)
infoi显示有关已安装的嵌套包的信息和其他有用的系统信息

generate 后可以加的选项如下:

名称别名描述
applicationapplication在单存储库中生成一个新应用程序(如果是标准结构,则转换为单存储库)
classcl生成一个新类
configurationconfigGenerate a CLI configuration file
controllerco生成控制器声明
decoratord生成自定义修饰器
filterf生成过滤器声明
gatewayga生成网关声明
guardgu生成保护声明
interceptoritc生成侦听器声明
interfaceitf生成接口
middlewaremi生成中间件声明
modulemo生成模块声明
pipepi生成管道声明
providerpr生成提供程序声明
resolverr生成解析程序声明
services生成服务声明
librarylib在单存储库中生成一个新库(如果是标准结构,则转换为单存储库)
sub-appappGenerate a new application within a monorepo
resourceres生成新的 CRUD 资源
//创建user模块,也可以使用 mo 别名生成
nest g module user 
nest g mo user 

//创建user控制器,也可以使用 co 别名生成
nest g controller user
nest g co user

//创建user服务,也可以使用 s 别名生成
nest g service user
nest g s user

像上方形式执行三次命令未免有些麻烦,你可以执行下方命令也可以实现创建模块、控制器以及服务的效果

nest g resource user

不过需要注意的是,在执行时需要选择风格,本篇文章选择的是 RESTful 风格。

RESTful风格

什么是RESTful

RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用 XML 格式定义或 JSON 格式定义。

RESTful和传统风格对比

请求方式含义传统风格RESTful
get查询所有http://localhost:3000/user/http://localhost:3000/user
查询单个http://localhost:3000/user/list?id=1http://localhost:3000/user/1
post增改http://localhost:3000/user/addhttp://localhost:3000/user
delete删除http://localhost:3000/user/deletehttp://localhost:3000/user
put更新http://localhost:3000/user/updatehttp://localhost:3000/user

版本控制

如果想在Nest中使用,需要在./src/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();

以user为例,在user.controller.ts中,将@Controller('user')修改为

@Controller({
    path: "user",
    version: "1"
})

此时我们再请求http://localhost:3000/user就会显示404,需要在 user 前加上版本号,即http://localhost:3000/v1/user

像上方的做法,就将所有请求方式都设置了版本。那如果我们只想设置某一种请求方式呢?

当然也是可以的,如给 user 中的 get 请求加上版本。

  @Get(':id')
  @version('1')
  findOne(@Param('id') id: string) {
    return this.userService.findOne(+id);
  }

code码规范

code码说明
200 OK成功
304 Not Modified协商缓存
400 Bad Request参数错误
401 Unauthorizedtoken错误
403 Forbidden referer origin验证失败
404 Not Found接口不存在
500 Internal Server Error服务端错误
502 Bad Gateway上游接口有问题或者服务器问题

持续更新…

标签:AppService,app,AppController,user,模块,快速,Nest,NestJS
From: https://blog.csdn.net/Zhoozie/article/details/140326134

相关文章

  • Linux捣鼓记录:快速搭建alist+aria2+qbittorrent
    简介:使用docker-compose创建alistaria2qbittorrent服务,前置条件安装docker及docker-compose插件,docker镜像仓库访问不了,建议配置代理用来拉取镜像。一、确认路径,确认UIDGID,确认端口路径alist挂载路径:-/home/dalong/app/alist:/opt/alist/data-/home/dalong:/homearia......
  • 无法识别的usb设备怎么解决?分享6个小技巧,快速解决
    USB设备是我们日常生活和工作中经常使用的外设之一,如U盘、键盘、鼠标、打印机等。有时我们会遇到USB设备无法识别的问题。这不仅影响工作效率,还可能导致数据丢失。本文将详细探讨USB设备无法识别的原因及其解决方法。摘要USB设备无法识别的原因及解决方法如下:1、硬件故障:......
  • 离散傅里叶变换(DFT)和快速傅里叶变换(FFT)
    离散傅里叶变换(DFT)和快速傅里叶变换(FFT)是信号处理和数字信号处理中的基本工具。它们用于将时间域的信号转换为频率域的表示,帮助分析信号的频谱成分。1.离散傅里叶变换(DFT)1.1DFT的基本概念DFT是将离散时间信号转换为频域表示的工具。对于长度为N的离散信号x[n],其DFT定义为:......
  • 2024短视频IP快速起号实战课,0基础打造爆款内容设计+运营
    摘要:本教程旨在系统阐述从零基础到实现短视频IP快速起号的全过程,涵盖内容设计、粉丝运营、变现策略及关键技术点,共计23节课程,为短视频创作者及企业营销人员提供一套全面而实用的实战指南。第一章:短视频IP起号基础起号意义解析:深入探讨短视频平台中快速起号对于品牌建立、......
  • 三分钟,快速了解区块链技术!
    区块链,一种分布式账本技术,是一种分布式数据存储技术。链式存储结构:区块链是一种分布式账本技术,其核心是通过去中心化的方式来存储和管理数据。1交易发起与验证发起交易:用户在计算机上发起交易请求。这交易可以是转账、资产交换或其他类型的信息交换。节点传播:交易请求会通......
  • 快速傅里叶变换复习笔记
    .real()成员函数FFT的本质是快速计算多项式的点值表示对负实数的四舍五入需要-0.5编写函数接收数组地址时,注意不能破坏原数组FFT有较为严重的精度问题,double甚至难以准确计算两个\(10^9\)级别的整数相乘的结果,即使采用longdouble也时常无法得到准确的答案,这或许也是模板题中......
  • 使用Python Flask快速构建一个api server
    使用flask快速构建一个apiserver代码如下:fromflaskimportFlask,jsonify,requestapp=Flask(__name__)#定义一个路由,当访问根路径时返回欢迎信息@app.route('/')defhome():return'Hello,thisisasimpleAPI!'#定义一个路由,接受GET请求并返回JSON响......
  • APICloud+ cosClient快速构建APP
    APICloud简介APICloud是一个移动低代码开发平台,对于不同的需求场景提供了不同的功能模块,并快速构建企业级应用。cosClient模块简介cosClient是腾讯云对象存储(COS)针对APICloud平台桥接原生SDK封装的模块,可以使用cosClient快速接入并使用COS的功能,目前支持Android、iOS。在APIC......
  • 如何快速实现一个无缝轮播效果
    ......
  • SpringBoot集成Rabbitmq快速启动示例
    RabbitMQ六种模式示例源码:ghdefe/rabbitmq-demo此项目分别演示六种模式:简单模式、工作模式、发布/订阅模式、路由模式、主题模式、RPC模式简单模式:生产者直接发送消息到队列、消费者直接消费队列、不经过交换机工作模式:与简单模式一致,只是变成多个消费者消费同一......