# 介绍
Nest.js 官网介绍
Nest (NestJS) 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的开发框架。它利用 JavaScript 的渐进增强的能力,使用并完全支持 TypeScript (仍然允许开发者使用纯 JavaScript 进行开发),并结合了 OOP (面向对象编程)、FP (函数式编程)和 FRP (函数响应式编程)。
在底层,Nest 构建在强大的 HTTP 服务器框架上,例如 Express (默认),并且还可以通过配置从而使用 Fastify !
Nest 在这些常见的 Node.js 框架 (Express/Fastify) 之上提高了一个抽象级别,但仍然向开发者直接暴露了底层框架的 API。这使得开发者可以自由地使用适用于底层平台的无数的第三方模块。
简单理解就是原生支持 TypeScript ,可以在项目中使用Express /或者配置之后使用Fastify
# 项目创建
使用 Nest CLI 来创建项目,主要创建方式有两种,当前项目用的是 yarn, 因为速度会快点,注意如果是macos 的话需要在指令前输入 sudo 然后输入密码后下载
1、使用npm
- npm i -g @nestjs/cli
- nest new nest_api
2、使用yarn
- yarn global add @nestjs/cli
- nest new nest_api
项目生成后,可以输入 yarn start 启动项目也可以使用 yarn start:dev
推荐使用 yarn start:dev 因为这修改文件后,想看到修改之后的结果必须要重新启动应用服务,使用yarn start:dev 可以监视特定文件,有变化后会重新刷新服务
启动后 打开浏览器可以访问 http://localhost:3000/ 地址。
生成项目后结构是这样的
这是几个比较核心的文件
user
├── app.controller.spec.ts
├── app.controller.ts
├── app.module.ts
├── app.service.ts
# 分析
在入口文件 main.ts 中 可以看调用了一个 bootstrap 函数 ,在这个函数中使用了 NestFactory 创建了一个根模块为
AppModule 的 Nest 服务 并侦听服务端口 3000
main.ts 文件 | |
import { NestFactory } from '@nestjs/core'; | |
import { AppModule } from './app.module'; | |
async function bootstrap() { | |
const app = await NestFactory.create(AppModule); | |
await app.listen(3002);// 端口 可以自己配置 | |
console.log('http://localhost:3002/'); | |
} | |
bootstrap(); |
在入口文件中会发现只引入了一个文件 app.module,接下来进入到 app.module.ts 中,可以看到 在 app.module.ts 使用了一个
@module 装饰器的类 来处理了两个文件(AppController 和 AppService) @module 解释:
每个模块 (.module.ts,app.module.ts 就是项目的根模块) 都需要一个 @module 类
@module 装饰器接受的是一个对象参数,有四个字段并且都是数组类型的分别是:
- controllers: 控制器 - 负责处理请求并返回响应数据给客户端
- providers: 模块中所有用到的功能类,模块内共享实用;
- imports: 导入其他模块中导出的 Providers,以实现共享
- exports: 导出其他模块需要共享的 Providers
进入 app.controller.ts 页面,可以看到页面中用到了两个装饰器 @Controller() 和 @Get() 每个控制器页面都需要
使用 @Controller() 装饰器来定义
<!--app.controller.ts--> | |
import { Controller, Get,} from '@nestjs/common'; | |
import { AppService } from './app.service'; | |
@Controller() | |
export class AppController { | |
constructor(private readonly appService: AppService) {} | |
@Get() | |
getHello(): string { | |
return this.appService.getHello(); | |
} | |
} |
@Controller() 控制器,目的是接收应用程序的特定请求。路由机制控制哪个控制器接收哪个请求,可以在控制器中传入一个路径参数
作为访问这个控制器的主路径.
例:
在 @Controller () 传入 'api'
<!--app.controller.ts--> | |
import { Controller, Get } from '@nestjs/common'; | |
import { AppService } from './app.service'; | |
@Controller('api') | |
export class AppController { | |
constructor(private readonly appService: AppService) {} | |
@Get() | |
getHello(): string { | |
return this.appService.getHello(); | |
} | |
} |
这时候查看 http://localhost:3000/ 会发现 页面返回
{"statusCode":404,"message":"Cannot GET /","error":"Not Found"} |
这是因为控制器中传入了路径参数 'api', 在路径后输入刚才配置的 'api',
http://localhost:3000/api
后可以正常返回 Hello World!
@Get() 是属于请求方法装饰器,当前文件的 @Get () 表示对 getHello 方法进行修饰,
表示这个方法会被 GET 请求调用。也可以在方法中传入一个字符串或是字符串数组(这个字符串可以是固定的路径也可以是通配符) 常用的 HTTP 请求装饰器有:
- @Get
- @Post
- @Put
- ...
# 参数
Nest 还提供了一组有用的参数装饰器,可以将它们与 HTTP 路由处理程序一起使用。下面是提供的装饰器和它们代表的普通 Express(或
Fastify)对象的列表
使用 装饰器时需要在 '@nestjs/common' 中引入
import { Injectable } from '@nestjs/common'; | |
@Injectable() | |
export class AppService { | |
getHello(): string {--> | |
return 'Hello World!'; | |
} | |
} |
除了使用 @Controller () 和 请求方法装饰器 配置路由之外还可以在全局配置一个路由
main.ts; | |
import { NestFactory } from "@nestjs/core"; | |
import { AppModule } from "./app.module"; | |
async function bootstrap() { | |
const app = await NestFactory.create(AppModule); | |
app.setGlobalPrefix("blog"); // 设置全局路由前缀 | |
await app.listen(3002); // 端口 可以自己配置 | |
console.log("http://localhost:3002/"); | |
} | |
bootstrap(); |
回到 app.controller.ts 文件,发现请 get 方法请求了一个函数名为 getHello 的方法而这个方法 return
了来自 appService 文件中的 getHello 方法, 跟着思路打开 app.service.ts 可以发现 有一个被 @Injectable ()
装饰装饰的类 AppService,可以发现具体处理逻辑的地方在这个文件
import { Injectable } from '@nestjs/common'; | |
@Injectable() | |
export class AppService { | |
getHello(): string { | |
return 'Hello World!'; | |
} | |
} |
@Injectable () 解释: 拦截器是 @Injectable () 的类。拦截器应该实现 NestIntercept 接口。
# 总结一下
1、文件介绍:
- main.ts - 项目的入口文件
- app.module.ts - 应用程序的根模块,对相关组件进行分组 (Module)
- app.controller.ts- 主控制器文件 - 控制路由 (Controller)
- app.service.ts - 实现和隔离业务逻辑
- app.controller.spec.ts- 针对控制器的单元测试
2、app.module.ts 是项目的主要模块,为了方便控制管理项目。同时还可以创建多个模块,如用户模块、文章模块、评论管理模块...
可以使用在终端中使用快捷命令创建
例: 创建一个用户模块 users
nest g resource [名称]
nest g co users
nest g mo users
nest g s users
创建完后会在 src 下面生成 users 文件结构如下:
users
├── users.controller.spec.ts
├── users.controller.ts
├── users.module.ts
├── users.service.ts
注意:需要在 app.module.ts 中的 imports 中导入 users.module.ts 文件
<!--app.module.ts--> | |
import { Module } from '@nestjs/common'; | |
import { AppController } from './app.controller'; | |
import { AppService } from './app.service'; | |
// 引入文件 | |
import { UsersModule } from './users/users.module'; | |
@Module({ | |
controllers: [AppController], | |
providers: [AppService], | |
imports: [UsersModule], | |
}) | |
export class AppModule {} |
注意:需要手动将
users.service.ts
文件和users.controller.ts
文件导入 到users.module.ts
文件中。
<!--users.module.ts--> | |
import { Module } from '@nestjs/common'; | |
import { Users } from './entities/users.entities'; | |
import { UsersController } from './users.controller'; | |
import { UsersService } from './users.service'; | |
@Module({ imports:[], | |
controllers: [UsersController] | |
,providers:[UsersService]}) | |
export class UsersModule {} |
我们以为自己是理性的,我们以为自己的一举一动都是有其道理的。但事实上,我们的绝大多数日常行为,都是一些我们自己根本无法了解的隐蔽动机的结果。
————《乌合之众》