上手nestjs

如何安装nestjs

因为后续会选择nestjs创建不同的应用,所以推荐安装nestjs的官方生成工具

1
2
3
4
5
npm i -g @nestjs/cli

nest new project-name

nest new project-name --strict

因为nestjs完全支持使用typescript构建,所以传递 –strict 可以使项目有更加严格的功能集

创建提示如下:

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
PS C:\nestjs> nest new project-name --strict
✨ We will scaffold your app in a few seconds..

✔ Which package manager would you ❤️ to use? npm
CREATE project-name/.prettierrc (54 bytes)
CREATE project-name/eslint.config.mjs (869 bytes)
CREATE project-name/nest-cli.json (179 bytes)
CREATE project-name/package.json (2054 bytes)
CREATE project-name/README.md (5126 bytes)
CREATE project-name/tsconfig.build.json (101 bytes)
CREATE project-name/tsconfig.json (699 bytes)
CREATE project-name/src/app.controller.ts (286 bytes)
CREATE project-name/src/app.module.ts (259 bytes)
CREATE project-name/src/app.service.ts (150 bytes)
CREATE project-name/src/main.ts (236 bytes)
CREATE project-name/src/app.controller.spec.ts (639 bytes)
CREATE project-name/test/jest-e2e.json (192 bytes)
CREATE project-name/test/app.e2e-spec.ts (699 bytes)

▹▹▹▹▹ Installation in progress... ☕

✔ Installation in progress... ☕

🚀 Successfully created project project-name
👉 Get started with the following commands:

$ cd project-name
$ npm run start


Thanks for installing Nest 🙏
Please consider donating to our open collective
to help us maintain this package.

默认此命令是安装好所有的依赖,所以你可以直接进入到project-name目录并直接输入npm run start运行项目

当终端出现如下命令,即表示项目启动成功

1
2
3
4
5
6
7
8
9
10
PS C:\nestjs\project-name> npm run start

> project-name@0.0.1 start
> nest start

[Nest] 20636 - 2025/09/13 18:32:20 LOG [NestFactory] Starting Nest application...
[Nest] 20636 - 2025/09/13 18:32:20 LOG [InstanceLoader] AppModule dependencies initialized +9ms
[Nest] 20636 - 2025/09/13 18:32:20 LOG [RoutesResolver] AppController {/}: +4ms
[Nest] 20636 - 2025/09/13 18:32:20 LOG [RouterExplorer] Mapped {/, GET} route +3ms
[Nest] 20636 - 2025/09/13 18:32:20 LOG [NestApplication] Nest application successfully started +2ms

表示nest正在启动nest应用,然后初始化了AppModule,初始化了一个Appcontroller,路由为 /,然后 / 下有一个 GET 方法,最终nest应用成功启动,这意味着,我们可以在127.0.0.1:3000/ 直接发送一个GET请求,返回了 “Hello World!”

1
2
3
4
5
6
7
8
9
10
11
12
13
目录结构如下:
src
|
—— app.controller.spec.ts (controller单元测试)
|
—— app.controller.ts (controller文件)
|
—— app.module.ts (应用的根模块文件)
|
—— app.service.ts (具有单一方法的基本服务)
|
—— main.ts (应用的入口文件)

如何编写nestjs代码

首先我们通过npm run start:dev可以运行服务并监视文件中的更改

这样当我们编写nestjs代码的时候,保存文件后,nestjs将会重新编译,提升开发效率

nestjs推荐安装 eslintprettier 两个包来统一开发的 lint 和 format

如何debug代码

方式一:vscode断点调试

这里以vscode为例,通常用来开发ts相关的项目

我们来到运行和调试一栏,主动添加配置,选择 nodejs:通过npm启动

然后在configurations中就会出现以下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"name": "Launch via NPM",
"request": "launch",
"runtimeArgs": [
"run-script",
"debug"
],
"runtimeExecutable": "npm",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
}

此时我们可以修改配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"name": "Launch nestjs",
"request": "launch",
"runtimeArgs": [
"run",
"start:dev"
],
"runtimeExecutable": "npm",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
}

此时我们即可通过点击 debug nestjs 左侧的绿色执行按钮启动项目并支持断点调试

方式二:官方的devtools

需要付费

主要是查看模块间的依赖关系以及是否有循环依赖

了解nestjs的基础概念

Controllers

控制器:主要负责处理传入的请求并将响应发送回客户端

你可以理解为路由的入口,通过不同的模块申明不同的入口,例如user模块,就会有以下restful资源

  • 【获取所有用户信息】GET /user
  • 【获取单个用户信息】GET /user/:id
  • 【新增某个用户信息】POST /user/:id
  • 【更新某个用户信息】PATCH /user/:id
  • 【删除某个用户信息】DELETE /user/:id

在此资源之上,你可以通过装饰器来申明通过什么路径来调用、获取请求参数、重定向、错误处理等等

providers

提供程序:nestjs的核心概念,很多nestjs的基础类都是被看作是提供程序,例如 services, repositories, factories, helpers。关键的思想是依赖注入(DI)

  1. provider不是手动new出来的,而是由nest的 IOC 容器来负责provider的实例化以及生命周期的管理
  2. 每个provider只需要负责完成它自己的功能,控制器只负责路由,逻辑复用和扩展交给provider
配置方式 示例 使用场景 设计理念 总结
useClass [ { provide: Token, useClass: Logger } ] 用某个类作为实现,常用于替换具体实现
开发环境用consoleLogger,
生产用fileLogger
面向接口编程。只要 token 一致,背后实现可随时切换。 面向抽象,随时换实现
useValue [ { provide: Token, useValue: { db: 'mysql', port: 3306 } } ] 注入常量、配置项、工具函数等 值即是服务,直接把一个对象或函数注册到 IoC 容器,避免硬编码。 配置即依赖,简单直接
useFactory [ { provide: Token, useFactory: (config: ConfigService) => new DB(config.dbUrl), inject: [ConfigService] } ] 构造逻辑复杂,依赖其他 provider 的场景。 工厂模式 + DI。容器只管执行工厂函数,返回什么就注入什么。 动态构造,灵活注入
useExisting [ { provide: Token, useExisting: ConsoleLogger } ] 给已有 provider 起别名。
例:AppLoggerToken 与Token 指向同一实例。
“指针”绑定。多个 token 引用同一 provider,避免重复实例化。 别名绑定,复用实例

Modules

modules:提供 Nest 用于有效组织和管理应用程序结构的元数据
providers:Nest 注入器将实例化的提供程序,这些程序至少可以在本模块中共享
controllers:本模块中定义的、需要实例化的控制器集合
imports:本模块所需的提供程序的模块列表(从其他模块export之后再在本模块import)
exports:这些提供程序由本模块提供,并应在导入本模块的其他模块中可用。您可以使用提供程序本身,也可以只使用其标记(提供值)

Middleware

中间件是在路由处理程序之前调用的函数,中间件函数可以访问请求和响应对象,以及应用程序请求-响应周期中的 next() 中间件函数

几乎等同于express的中间件

Exception filters

Exception filters:负责处理应用程序中所有未处理的异常
通常用来处理HTTP标准异常、自定义异常、业务异常以及未捕捉到的异常

Pipes

pipes的作用

  1. 转换:将输入数据转换为所需的形式(例如,从字符串转换为整数)
  2. 验证:评估输入数据,如果有效,只需将其原封不动地传递;否则,抛出异常

Guards

guards:守卫是一个用 @Injectable() 装饰器注释的类,它实现了 CanActivate 接口。

作用:只有一个责任。它们确定给定请求是否由路由处理程序处理,具体取决于运行时存在的某些条件(如权限、角色、ACL 等)。这通常称为授权。

Interceptors

Interceptors:拦截器是一个用 @Injectable() 装饰器注释的类,实现了 NestInterceptor 接口。

功能:

  1. 在方法执行之前/之后绑定额外的逻辑
  2. 转换从函数返回的结果
  3. 转换从函数抛出的异常
  4. 扩展基本函数行为
  5. 根据特定条件完全覆盖函数(例如,用于缓存目的)

了解nestjs核心模块的执行顺序

【nest应用启动时初始化】

sequenceDiagram
    participant AppModule
    participant NestFactory
    participant IoCContainer as IoC 容器
    participant Provider
    participant Controller

    NestFactory->>AppModule: 读取根模块
    AppModule->>NestFactory: 返回 imports/controllers/providers
    NestFactory->>IoCContainer: 注册 Providers
    IoCContainer->>Provider: 实例化依赖 (构建依赖树)
    NestFactory->>Controller: 注册 Controllers & 路由
    Note over NestFactory,Controller: 应用初始化完成

【请求生命周期】

sequenceDiagram
    participant Client
    participant Middleware
    participant Guard
    participant Interceptor as Interceptor(before)
    participant Pipe
    participant Controller
    participant Service
    participant InterceptorAfter as Interceptor(after)
    participant ExceptionFilter
    participant Response

    Client->>Middleware: 进入应用
    Middleware->>Guard: 继续
    Guard->>Interceptor: canActivate 成功
    Interceptor->>Pipe: before handler
    Pipe->>Controller: 参数验证 & 转换
    Controller->>Service: 调用业务逻辑
    Service-->>Controller: 返回数据
    Controller->>InterceptorAfter: 结果返回
    InterceptorAfter->>Response: 加工结果后响应
    Note over Guard,Response: 如果任意阶段抛错 → ExceptionFilter 捕获


上手nestjs
https://shiyuq.github.io/2025/09/12/上手nestjs/
作者
Jack
发布于
2025年9月12日
许可协议