Nest.js简介

  • 中文官方文档 英文官方文档

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

  • 使用nestjs的开发体验就像是搭积木一样,每一块业务逻辑基本都是有模块(module)来控制,包括其对应下的接口等,这样使得每一块业务都非常的清晰.

快速上手(安装和新建项目)

  1. 安装
npm i -g @nestjs/cli
  1. 新建项目
nest new project-name

项目文件解析

+-- dist[目录]                      // 编译后的目录,用于预览项目
+-- node_modules[目录] // 项目使用的包目录,开发使用和上线使用的都在里边
+-- src[目录] // 源文件/代码,程序员主要编写的目录
| +-- app.controller.spec.ts // 对于基本控制器的单元测试样例
| +-- app.controller.ts // 控制器文件,可以简单理解为路由文件
| +-- app.module.ts // 模块文件,在NestJS世界里主要操作的就是模块
| +-- app.service.ts // 服务文件,提供的服务文件,业务逻辑编写在这里
| +-- app.main.ts // 项目的入口文件,里边包括项目的主模块和监听端口号
+-- test[目录] // 测试文件目录,对项目测试时使用的目录,比如单元测试...
| +-- app.e2e-spec.ts // e2e测试,端对端测试文件,测试流程和功能使用
| +-- jest-e2e.json // jest测试文件,jset是一款简介的JavaScript测试框架
+-- .eslintrc.js // ESlint的配置文件
+-- .gitignore // git的配置文件,用于控制哪些文件不受Git管理
+-- .prettierrc // prettier配置文件,用于美化/格式化代码的
+-- nest-cli.json // 整个项目的配置文件,这个需要根据项目进行不同的配置
+-- package-lock.json // 防止由于包不同,导致项目无法启动的配置文件,固定包版本
+-- package.json // 项目依赖包管理文件和Script文件,比如如何启动项目的命令
+-- README.md // 对项目的描述文件,markdown语法
+-- tsconfig.build.json // TypeScript语法构建时的配置文件
+-- tsconfig.json // TypeScript的配置文件,控制TypeScript编译器的一些行为
  • src目录下文件说明
+-- src[目录]                       // 源文件/代码,程序员主要编写的目录
| +-- app.controller.spec.ts // 对于基本控制器的单元测试样例
| +-- app.controller.ts // 控制器文件,可以简单理解为路由文件
| +-- app.module.ts // 模块文件,在NestJS世界里主要操作的就是模块
| +-- app.service.ts // 服务文件,提供的服务文件,业务逻辑编写在这里
| +-- app.main.ts // 项目的入口文件,里边包括项目的主模块和监听端口号

简单刨析

  1. Module

是用来对外暴露当前模块,以及该模块下需要用到的controllerservice都需要在module中引入并注册,最终在app.module中集中引入。官方推荐使用命令行的形式生成一个module

# 生成一个完整的module
nest g module module_name

# 生成一个不带测试文件的module
nest g module module_name --no-spec
  1. controller

nestjs作为web服务对外暴露请求接口路径,controller就是用来处理这些请求路径的控制器,一个controller对应一个模块模块下有多个具体接口。我们一般在controller中编写接口但是不编写业务逻辑

# 生成一个完整的controller
nest g controller controller_name

# 生成一个不带测试文件的controller
nest g controller controller_name --no-spec
  1. service

controller中每个独立请求的具体处理逻辑,每个controller在使用service的时候需要在constructor注入该service。总的来讲就是我们在controller中编写的接口而对应的业务逻辑就在这里编写,同样官方推荐使用命令行的形式创建service

# 生成一个完整的service
nest g service service_name

# 生成一个不带测试文件的service
nest g service service_name --no-spec

基本案例展示:

  • 这里我使用nestjs搭建了一个小的服务器并对外提供几个接口,使用到的知识就是上面提到的module,service以及controller等结合使用,以及一些装饰符可以帮助我们获取接口的请求数据,请求体,请求头数据等,实现get,post以及动态路由的操作!

boys模块(boys文件夹)

  1. main.ts(整个项目的入口文件)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('api'); //设置全局访问路径前缀
await app.listen(3000);
}
bootstrap();
  1. boys.controller.ts(路由以及接口的编写)
// 引入请求方法以及请求参数修饰符等
/*
请求参数修饰符:
1. Request 里面有全部的请求体数据
get请求获取请求参数: (@Request req) -> req.query
post请求后去请求参数: (@Request req) -> req.body

2. Query get请求参数的简写获取形式 (@Query query) -> query
2. Body get请求参数的简写获取形式 (@Body body) -> body

获取url上的参数修饰符
1. Request获取url上的参数: (@Request req) -> req.param
2. Param: (@Param param) -> param

获取请求头参数
1. Headers: (@Headers headers) -> headers
*/
import {
Controller,
Get,
Request,
Post,
Query,
Body,
Param,
Headers,
} from '@nestjs/common';
import { BoysService } from './boys.service';

/*
我们可以认为 Controller 是用户配置路由的地方
根据以下代码我们如果想要获取数据就需要输入路径为: /boys/getBoys
当然我们要想在全局中设置初识路径,可以在main.ts中设置 setGlobalPrefix('全局路径')
*/
@Controller('boys')
export class BoysController {
// 创建一个构造函数
constructor(private BoysService: BoysService) {
/*
BoysService: BoysService 等价于 this.BoysService = new BoysService()
*/
}
// 填写一个get请求
@Get() //当然也可以在 @Get('/添加的路径') 来限制访问路径
getBoys(): Object {
// 这里我们就可以直接返回 service 中设置好的函数(业务逻辑的编写修改)即可
return this.BoysService.getBoys();
}

/* -------------------------- 请求参数的获取(修饰符 Request Query ) ---------------------------*/

// 填写一个post请求 获取请求参数需要通过 Request 修饰符,当然也可以直接使用 @Body() body来简化
@Post('postAdd')
addPostBoys(@Request() req): Object {
// 我们可以打印一下这个修饰请求参数
console.log('请求参数post:', req.body);

return { msg: 'Post-Success!', data: req.body };
}

// 填写一个get请求 获取请求参数需要通过 Request 修饰符
@Get('getAdd')
addGetBoys(@Query() query): Object {
// 我们可以打印一下这个修饰请求参数
console.log('请求参数get:', query);

return { msg: 'Get-Success!', data: query };
}

/* --------------------- 获取动态路由(获取url上的参数,获取请求头参数等) ------------------------- */
// 填写一个get请求 获取请求参数需要通过 Request 修饰符
@Get('Add/:id/:name')
// 设置修饰符获取对应的参数 (Param,Headers)
addBoys(@Param() param, @Headers() headers): Object {
// 我们可以打印一下这个修饰请求参数
console.log('请求参数param:', param, headers);

return { msg: 'GetParam-Success!', data: param, headers: headers };
}
}
  1. boys.module.ts(整个模块的入口文件)
import { Module } from '@nestjs/common';
import { BoysController } from './boys.controller';
import { BoysService } from './boys.service';

@Module({
controllers: [BoysController],
providers: [BoysService],
})
export class BoysModule {}

  1. boys.service.ts(接口处理数据的业务逻辑)
import { Injectable } from '@nestjs/common';

/*
我们可以认为,service是用来编写业务逻辑的,因此要想实现一个完整的
模块化,在这里我们要编写对应模块下对应接口的业务逻辑,包括 返回响应的数据
要处理的业务逻辑等..
*/

@Injectable()
export class BoysService {
// 对应 Controller 中的 getBoys接口,使用一个方法来处理并返回数据
getBoys(): Object {
return {
code: 200,
data: ['小明', '小张'],
msg: '请求数据成功!',
};
}

addBoys(): Object {
return {
code: 200,
data: {
id: 4,
name: '马老师',
age: 57,
},
msg: '新增数据成功!',
};
}
}

本篇博客参考自技术胖的博文,原文地址