返回首页

NestJS 基础入门教程

NestJS 基础入门教程

1. NestJS 简介

NestJS 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架。

  • 架构: 深受 Angular 启发,采用模块化架构。
  • 语言: 完美支持 TypeScript(但也支持 JavaScript)。
  • 底层: 默认使用 Express,也可切换到 Fastify。
  • 核心特性: 依赖注入 (DI)、面向切面编程 (AOP)、装饰器语法。

2. 环境搭建与安装

需要先安装 Node.js。然后使用 NPM 安装 Nest CLI 工具。

# 全局安装 Nest CLI
npm i -g @nestjs/cli

# 创建新项目
nest new project-name

进入项目目录并启动开发服务器:

cd project-name
npm run start:dev

打开浏览器访问 http://localhost:3000,你应该能看到 "Hello World!"。


3. 核心概念

NestJS 应用主要由以下几个核心部分组成:

  1. Modules (模块): 组织代码的基本单元,使用 @Module() 装饰器。
  2. Controllers (控制器): 处理传入的请求并返回响应,使用 @Controller() 装饰器。
  3. Providers (提供者): 包含业务逻辑的服务、仓库等,通过依赖注入使用,使用 @Injectable() 装饰器。

4. 实战:构建一个 "图书管理" API (CRUD)

我们将创建一个简单的 REST API 来增删改查图书信息。

4.1 生成资源

使用 CLI 快速生成模块、控制器和服务:

nest g resource books

选择 "REST API" -> "No" (不生成 CRUD 代码,我们手动写以便学习)。

此时目录结构如下:

src/
  books/
    books.module.ts
    books.controller.ts
    books.service.ts

4.2 定义数据结构 (DTO & Entity)

1. 创建实体 (src/books/entities/book.entity.ts)

export class Book {
  id: number;
  title: string;
  author: string;
  price: number;
}

2. 创建 DTO (数据传输对象) DTO 用于验证客户端发送的数据。 (需安装验证库: npm i class-validator class-transformer)

(src/books/dto/create-book.dto.ts)

import { IsString, IsInt, Min } from "class-validator";

export class CreateBookDto {
  @IsString()
  title: string;

  @IsString()
  author: string;

  @IsInt()
  @Min(0)
  price: number;
}

4.3 实现业务逻辑 (Service)

在 Service 中处理数据逻辑。

(src/books/books.service.ts)

import { Injectable, NotFoundException } from "@nestjs/common";
import { Book } from "./entities/book.entity";
import { CreateBookDto } from "./dto/create-book.dto";

@Injectable()
export class BooksService {
  private books: Book[] = [];
  private idCounter = 1;

  // 查询所有
  findAll(): Book[] {
    return this.books;
  }

  // 根据ID查询
  findOne(id: number): Book {
    const book = this.books.find((b) => b.id === id);
    if (!book) {
      throw new NotFoundException(`Book with ID ${id} not found`);
    }
    return book;
  }

  // 创建图书
  create(createBookDto: CreateBookDto): Book {
    const newBook: Book = {
      id: this.idCounter++,
      ...createBookDto,
    };
    this.books.push(newBook);
    return newBook;
  }

  // 删除图书
  remove(id: number): void {
    const index = this.books.findIndex((b) => b.id === id);
    if (index === -1) {
      throw new NotFoundException(`Book with ID ${id} not found`);
    }
    this.books.splice(index, 1);
  }
}

4.4 实现控制器 (Controller)

Controller 负责定义路由和处理 HTTP 请求。

(src/books/books.controller.ts)

import {
  Controller,
  Get,
  Post,
  Body,
  Param,
  Delete,
  ParseIntPipe,
} from "@nestjs/common";
import { BooksService } from "./books.service";
import { CreateBookDto } from "./dto/create-book.dto";

@Controller("books") // 路由前缀: /books
export class BooksController {
  constructor(private readonly booksService: BooksService) {}

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

  @Get(":id")
  findOne(@Param("id", ParseIntPipe) id: number) {
    // ParseIntPipe 会自动将 url 参数转为数字
    return this.booksService.findOne(id);
  }

  @Post()
  create(@Body() createBookDto: CreateBookDto) {
    return this.booksService.create(createBookDto);
  }

  @Delete(":id")
  remove(@Param("id", ParseIntPipe) id: number) {
    return this.booksService.remove(id);
  }
}

4.5 注册模块

CLI 应该已经自动在 app.module.ts 中引入了 BooksModule。如果没有,请手动添加:

import { Module } from "@nestjs/common";
import { BooksModule } from "./books/books.module";

@Module({
  imports: [BooksModule],
  controllers: [],
  providers: [],
})
export class AppModule {}

5. 启用全局验证管道

为了让 DTO 中的验证装饰器生效,需要在 main.ts 中配置全局管道。

(src/main.ts)

import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { ValidationPipe } from "@nestjs/common";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // 启用全局验证管道
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true, // 自动剔除 DTO 中未定义的属性
      forbidNonWhitelisted: true, // 如果存在未定义属性则抛出错误
    })
  );

  await app.listen(3000);
}
bootstrap();

6. 测试 API

现在你可以使用 Postman 或 curl 测试接口:

  1. POST http://localhost:3000/books
    {
      "title": "NestJS Guide",
      "author": "John Doe",
      "price": 29
    }
    
  2. GET http://localhost:3000/books
  3. GET http://localhost:3000/books/1
  4. DELETE http://localhost:3000/books/1