nestjs快速入门

2025/3/5 nestjsnode

🌙 nestjs快速入门

🌙 一、nest 简介

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

在底层,Nest 使用了强大的 HTTP 服务器框架,如 Express(默认)和可选的 Fastify

Nest 提供了一种开箱即用的应用程序架构,允许开发者和团队创建高度可测试、可扩展、松耦合且易于维护的应用程序。该架构深受 Angular 启发。

nestjs官网 (opens new window)

🌙 二、使用 @nestjs/cli

🌙 1.安装

安装nestjs的最简单方法是使用npm,通过运行以下命令来安装nestjs:

pnpm i -g @nestjs/cli

# 查看 nest cli 命令
nest -h 
1
2
3
4

@nestjs/cli 命令如下:

name alias description
application application Generate a new application workspace
class cl Generate a new class
configuration config Generate a CLI configuration file
controller co Generate a controller declaration
decorator d Generate a custom decorator
filter f Generate a filter declaration
gateway ga Generate a gateway declaration
guard gu Generate a guard declaration
interceptor itc Generate an interceptor declaration
interface itf Generate an interface
library lib Generate a new library within a monorepo
middleware mi Generate a middleware declaration
module mo Generate a module declaration
pipe pi Generate a pipe declaration
provider pr Generate a provider declaration
resolver r Generate a GraphQL resolver declaration
resource res Generate a new CRUD resource
service s Generate a service declaration
sub-app app Generate a new application within a monorepo

🌙 2.创建项目

创建一个名为my-app的新项目,并使用nest new命令来创建一个新项目:

nest new my-app
cd my-app
pnpm run start
1
2
3
  • 目录结构
src
|-app.controller.spec.ts 控制器单元测试
|-app.controller.ts 一个具有单个路由的基本控制器
|-app.module.ts 应用程序的根模块
|-app.service.ts 一个具有单个方法的基本服务
|-main.ts 入口文件
1
2
3
4
5
6

main.ts内容:


import {NestFactory} from '@nestjs/core';
import {AppModule} from './app.module';

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    await app.listen(process.env.PORT ?? 3000);
}

bootstrap();

1
2
3
4
5
6
7
8
9
10
11

🌙 3.创建控制器 (opens new window)

  • nest g controller [name]

创建一个名为cats的控制器,并使用nest generate controller命令来创建一个新控制器:

nest g co cats
1

import {Controller, Get} from '@nestjs/common';

@Controller('cats')
export class CatsController {
    @Get()
    findAll(): string {
        return 'This action returns all cats';
    }
}

1
2
3
4
5
6
7
8
9
10
11

🌙 4.创建服务

  • nest g service [name]

创建一个名为cats的服务,并使用nest generate service命令来创建一个新服务:

nest g s cats
1

🌙 5.创建实体

创建一个名为cat的实体,并使用nest generate entity命令来创建一个新实体:

nest generate entity cat
1

🌙 6.创建数据访问层

创建一个名为cats的数据访问层,并使用nest generate module命令来创建一个新模块:

nest g mo cats
1

🌙 7.快捷生成CRUD

创建一个名为dogs的完整CRUD模版,使用nest generate resource dogs:

nest g res dogs
1

生成的目录如下:

src
├── dogs
│ ├── dogs.controller.spec.ts
│ ├── dogs.controller.ts
│ ├── dogs.module.ts
│ ├── dogs.service.spec.ts
│ ├── dogs.service.ts
│ ├── dto
│ │ ├── create-dog.dto.ts
│ │ └── update-dog.dto.ts
│ └── entities
│     └── dog.entity.ts
└── main.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14

🌙 三、nest 核心概念

模块(Module)、控制器(Controller)、服务(Service)、提供者(Provider)、中间件(Middleware)、异常过滤器(Exception Filters)、管道(Pipes)、守卫(Guards)与拦截器(Interceptors)

🌙 1.模块(module) (opens new window)

组织架构单元:使用 @Module() 装饰器声明,是应用程序的架构基础

生成命令:nest g mo [name]

典型用法示例:

  @Module({
    controllers: [CatsController],  // 注册控制器
    providers: [CatsService],       // 注册服务/提供者
    imports: [OtherModule],         // 导入依赖模块
    exports: [CatsService]          // 暴露服务供其他模块使用
  })
  
1
2
3
4
5
6
7

根据用途,可以分为:功能模块、共享模块、全局模块、动态模块

  • 功能模块: 使用 @Module() 装饰器,用于处理特定功能。SOLID 原则。
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
    controllers: [CatsController],
    providers: [CatsService],
    exports: [CatsService]
})

export class CatsModule {}
1
2
3
4
5
6
7
8
9
10
11
  • 共享模块: 模块默认为单例, 每个模块都是自动共享模块。一旦创建,它就可以被任何模块重用。

使用示例:

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
    // 导入非 全局模块
    imports: [CatsModule],
})
export class AppModule {}

1
2
3
4
5
6
7
8
9
  • 全局模块: 使用 @Global() 装饰器将模块设置为全局, 在任何地方都可直接使用,不需要额外导入。

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}

1
2
3
4
5
6
7
8
9
10
11
12
13
  • 动态模块: 动态模块允许在运行时动态创建模块。

import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
  exports: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?): DynamicModule {
    const providers = createDatabaseProviders(options, entities);
    return {
      // global: true, // 全局动态模块
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

使用:


import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
  exports: [DatabaseModule],
})
export class AppModule {}

1
2
3
4
5
6
7
8
9
10
11

🌙 2.控制器(controller) (opens new window)

控制器是应用程序的入口点,它定义了应用程序的 API 路由和请求处理逻辑。控制器使用 @Controller() 装饰器声明,并使用 @Get()@Post()@Put()@Delete() 等装饰器定义路由。

生成命令:nest g co [name]

典型用法示例:


import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';

@Controller('cats')
export class CatsController {
    @Get()
    findAll(@Req() request: Request): string {
        return 'This action returns all cats';
    }
    
    @Get(':id')
    findOne(@Param() params: any): string {
        console.log(params.id);
        return `This action returns a #${params.id} cat`;
    }

    @Post()
    @HttpCode(201)
    create(@Body() createCatDto: CreateCatDto) {
        return 'This action adds a new cat';
    }
}


export class CreateCatDto {
    name: string;
    age: number;
    breed: string;
}
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

🌙 3.服务(service)

服务是应用程序的核心,它提供了应用程序的业务逻辑和数据访问功能。

生成命令:nest g service [name]

典型用法示例:


import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
    private readonly cats: Cat[] = [];

    create(cat: Cat) {
        this.cats.push(cat);
    }

    findAll(): Cat[] {
        return this.cats;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

🌙 4.提供者(provider) (opens new window)

依赖注入核心:可以是 services, values, factories

通过构造函数注入:


import { Injectable, Optional, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
    // 构造函数注入
    // @Optional() 表示该参数是可选的
    constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
}
1
2
3
4
5
6
7
8
9

🌙 5.中间件(middleware) (opens new window)

中间件是应用程序的扩展点,它允许在请求处理之前或之后执行自定义逻辑。

日志中间件示例:


import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log('Request...');
    next();
  }
}

1
2
3
4
5
6
7
8
9
10
11
12

应用中间件示例:


import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

🌙 6.异常过滤器(exception filters) (opens new window)

Nest 内置异常层,负责处理应用程序中所有未处理的异常。

自定义异常:


export class ForbiddenException extends HttpException {
    constructor() {
        super('Forbidden', HttpStatus.FORBIDDEN);
    }
}

1
2
3
4
5
6
7

🌙 7.管道(pipes) (opens new window)

管道是一个被 @Injectable() 装饰器注解的类,它实现了 PipeTransform 接口。

数据转换/验证:用于参数预处理和验证

内置管道示例:ValidationPipe, ParseIntPipe

自定义管道示例:


import { PipeTransform, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { ZodSchema  } from 'zod';

export class ZodValidationPipe implements PipeTransform {
    constructor(private schema: ZodSchema) {}

    transform(value: unknown, metadata: ArgumentMetadata) {
        try {
            const parsedValue = this.schema.parse(value);
            return parsedValue;
        } catch (error) {
            throw new BadRequestException('Validation failed');
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

🌙 8.守卫(Guards) (opens new window)

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

如:用户角色权限控制(RolesGuard),用于检查用户是否具有访问权限


import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Roles } from './roles.decorator';

@Injectable()
export class RolesGuard implements CanActivate {
    constructor(private reflector: Reflector) {}

    canActivate(context: ExecutionContext): boolean {
        const roles = this.reflector.get(Roles, context.getHandler());
        if (!roles) {
            return true;
        }
        const request = context.switchToHttp().getRequest();
        const user = request.user;
        return matchRoles(roles, user.roles);
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

🌙 9.拦截器(Interceptors)

拦截器是一个被 @Injectable() 装饰器注解的类,并实现了 NestInterceptor 接口。

如: ExcludeNullInterceptor,用于将返回值为 null 值转换为空字符串 ''。


import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14