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 应用主要由以下几个核心部分组成:
- Modules (模块): 组织代码的基本单元,使用
@Module()装饰器。 - Controllers (控制器): 处理传入的请求并返回响应,使用
@Controller()装饰器。 - 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 测试接口:
- POST
http://localhost:3000/books{ "title": "NestJS Guide", "author": "John Doe", "price": 29 } - GET
http://localhost:3000/books - GET
http://localhost:3000/books/1 - DELETE
http://localhost:3000/books/1