NestJS 使用教程:从入门到实践的完整指南

2025-01-17 15:13:23

NestJS Logo

概述

NestJS 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的渐进式框架。它基于 TypeScript 构建,但同时也支持纯 JavaScript 的开发。NestJS 结合了现代 JavaScript 特性和设计模式,如依赖注入、面向对象编程(OOP)、函数式编程(FP)等,提供了一个灵活且强大的开发环境。

本文将通过实际案例和代码示例,详细介绍如何使用 NestJS 框架进行开发。我们将涵盖从项目初始化到模块创建、路由定义、数据库连接、微服务集成等多个方面,帮助开发者快速掌握 NestJS 的核心概念和开发技巧。

安装与项目初始化

1. 安装 NestCLI

NestCLI 是官方提供的命令行工具,可以帮助我们快速创建和管理 NestJS 项目。首先,确保你已经安装了 Node.js 和 npm。然后,通过以下命令全局安装 NestCLI:

npm i -g @nestjs/cli

2. 创建新项目

使用 NestCLI 创建一个新的 NestJS 项目非常简单。只需运行以下命令:

nest new my-nestjs-app

这将启动一个交互式向导,帮助你选择项目的配置选项。默认情况下,NestCLI 会生成一个包含基本结构的 NestJS 项目,包括 src 目录、main.ts 入口文件、app.module.ts 根模块等。

3. 项目结构

一个典型的 NestJS 项目结构如下所示:

my-nestjs-app/
├── src/
│   ├── app.controller.ts
│   ├── app.module.ts
│   ├── app.service.ts
│   └── main.ts
├── test/
└── package.json
  • src/:存放源代码文件。
  • main.ts:应用程序的入口文件。
  • app.module.ts:根模块,负责引导整个应用程序。
  • app.controller.tsapp.service.ts:默认生成的控制器和服务类。

模块化开发

1. 创建模块

模块是 NestJS 中组织代码的基本单元。每个模块可以包含控制器、服务、守卫、拦截器、管道、异常过滤器等多种组件。通过模块化开发,我们可以将应用程序分解为多个小的、可重用的模块,从而提高代码的可维护性和可测试性。

使用 NestCLI 创建一个新模块非常简单。例如,创建一个名为 cats 的模块:

nest generate module cats

这将在 src/ 目录下生成一个 cats.module.ts 文件,并将其自动导入到根模块中。

2. 模块结构

一个典型的模块结构如下所示:

// src/cats/cats.module.ts
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
  • controllers:定义模块中的控制器类。
  • providers:定义模块中的服务类和其他依赖项。

控制器与路由

1. 创建控制器

控制器负责处理 HTTP 请求并返回响应。每个控制器通常对应一组相关的路由。使用 NestCLI 创建一个控制器:

nest generate controller cats

这将在 src/cats/ 目录下生成一个 cats.controller.ts 文件,并在 cats.module.ts 中自动注册该控制器。

2. 定义路由

在控制器中,我们可以使用装饰器来定义路由。例如:

// src/cats/cats.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Get()
  findAll() {
    return this.catsService.findAll();
  }

  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return this.catsService.create(createCatDto);
  }
}
  • @Controller('cats'):定义控制器的基础路径为 /cats
  • @Get()@Post():分别定义 GET 和 POST 请求的处理方法。
  • @Body():提取请求体中的数据。

服务与业务逻辑

1. 创建服务

服务负责处理业务逻辑。使用 NestCLI 创建一个服务:

nest generate service cats

这将在 src/cats/ 目录下生成一个 cats.service.ts 文件,并在 cats.module.ts 中自动注册该服务。

2. 实现业务逻辑

在服务中,我们可以编写具体的业务逻辑。例如:

// src/cats/cats.service.ts
import { Injectable } from '@nestjs/common';

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

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

  findAll(): any[] {
    return this.cats;
  }
}
  • @Injectable():标记服务类为可注入的依赖项。
  • createfindAll:实现创建和查询猫的业务逻辑。

数据库连接

1. 安装 TypeORM

TypeORM 是一个流行的 ORM 库,支持多种数据库。首先,安装 TypeORM 和 MySQL 驱动:

npm install @nestjs/typeorm typeorm mysql2

2. 配置数据库连接

app.module.ts 中配置数据库连接:

// src/app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'password',
      database: 'test',
      autoLoadEntities: true,
      synchronize: true,
    }),
    CatsModule,
  ],
})
export class AppModule {}

3. 创建实体

实体表示数据库表。使用 NestCLI 创建一个实体:

nest generate entity cats/Cat

编辑生成的 cat.entity.ts 文件:

// src/cats/cat.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Cat {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  age: number;

  @Column()
  breed: string;
}

4. 使用实体

cats.module.ts 中引入实体:

// src/cats/cats.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { Cat } from './cat.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Cat])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}

微服务集成

1. 安装微服务依赖

安装 gRPC 和 Redis 依赖:

npm install @nestjs/microservices grpc @grpc/proto-loader redis

2. 配置微服务客户端

app.module.ts 中配置微服务客户端:

// src/app.module.ts
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'CAT_SERVICE',
        transport: Transport.GRPC,
        options: {
          url: 'localhost:50051',
          package: 'cat',
          protoPath: join(__dirname, './cats/cats.proto'),
        },
      },
    ]),
    CatsModule,
  ],
})
export class AppModule {}

3. 创建微服务服务器

创建一个微服务服务器:

// src/cats/cats.grpc.server.ts
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { CatsModule } from './cats.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    CatsModule,
    {
      transport: Transport.GRPC,
      options: {
        url: 'localhost:50051',
        package: 'cat',
        protoPath: join(__dirname, './cats/cats.proto'),
      },
    },
  );
  await app.listen();
}

bootstrap();

实战案例:构建 RESTful API

1. 创建用户模块

使用 NestCLI 创建一个用户模块:

nest generate module users

2. 创建用户控制器

创建用户控制器:

nest generate controller users

编辑 users.controller.ts 文件:

// src/users/users.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common';
import { UsersService } from './users.service';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }
}

3. 创建用户服务

创建用户服务:

nest generate service users

编辑 users.service.ts 文件:

// src/users/users.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  private readonly users = [];

  create(user: any) {
    this.users.push(user);
  }

  findAll(): any[] {
    return this.users;
  }
}

4. 创建用户实体

创建用户实体:

nest generate entity users/User

编辑 user.entity.ts 文件:

// src/users/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  username: string;

  @Column()
  email: string;

  @Column()
  password: string;
}

5. 配置用户模块

users.module.ts 中引入实体:

// src/users/users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}

结论

通过本文的介绍,我们详细学习了如何使用 NestJS 框架构建高效、可扩展的 Node.js 服务器端应用程序。从项目初始化到模块创建、路由定义、数据库连接、微服务集成等多个方面,我们掌握了 NestJS 的核心概念和开发技巧。希望这篇文章能够帮助你更好地理解 NestJS 并应用于实际项目中。

nestjs
用于构建高效且可扩展的服务器端应用程序的渐进式 Node.js 框架,深受 Angular 的启发。
TypeScript
MIT
69.4 k