NestJS 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架。它完美地结合了 OOP(面向对象编程)、FP(函数式编程)和 FRP(函数响应式编程)的元素。本文将带你从零开始了解 NestJS 的核心概念和基础用法。
环境准备与项目搭建
1. 环境准备
首先确保你的开发环境已经安装了 Node.js(推荐 v16 或更高版本)。然后全局安装 NestJS CLI:
npm i -g @nestjs/cli
2. 创建新项目
使用 CLI 创建新项目:
nest new my-nest-project
cd my-nest-project
选择包管理器(npm/yarn/pnpm)后,CLI 会自动创建项目结构并安装依赖。
3. 项目结构
src/
├── app.controller.spec.ts # 控制器测试文件
├── app.controller.ts # 基础控制器
├── app.module.ts # 根模块
├── app.service.ts # 基础服务
└── main.ts # 应用入口文件
核心概念
1. 控制器(Controllers)
控制器负责处理传来的请求和向客户端返回响应:
// src/app.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common';
import { AppService } from './app.service';
@Controller('api')
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('hello')
getHello(): string {
return this.appService.getHello();
}
@Post('message')
createMessage(@Body() message: { content: string }) {
return this.appService.createMessage(message);
}
}
2. 提供者(Providers)
提供者是 NestJS 中的基础概念,多数情况下用于封装业务逻辑:
// src/app.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
private messages: string[] = [];
getHello(): string {
return 'Hello World!';
}
createMessage(message: { content: string }): string {
this.messages.push(message.content);
return `Message created: ${message.content}`;
}
getAllMessages(): string[] {
return this.messages;
}
}
3. 模块(Modules)
模块是用来组织应用程序结构的基本单位:
// src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
4. 中间件(Middleware)
中间件是在路由处理程序之前调用的函数:
// src/common/middleware/logger.middleware.ts
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... Method: ${req.method}, Path: ${req.path}`);
next();
}
}
// 在模块中应用中间件
// src/app.module.ts
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
@Module({
// ... 其他配置
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('*');
}
}
5. 管道(Pipes)
管道用于数据转换和验证:
// src/common/pipes/validation.pipe.ts
import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';
@Injectable()
export class ValidationPipe implements PipeTransform<any> {
async transform(value: any, { metatype }: ArgumentMetadata) {
if (!metatype || !this.toValidate(metatype)) {
return value;
}
const object = plainToClass(metatype, value);
const errors = await validate(object);
if (errors.length > 0) {
throw new BadRequestException('Validation failed');
}
return value;
}
private toValidate(metatype: Function): boolean {
const types: Function[] = [String, Boolean, Number, Array, Object];
return !types.includes(metatype);
}
}
6. 异常过滤器(Exception Filters)
用于处理应用程序中的异常:
// src/common/filters/http-exception.filter.ts
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
response
.status(status)
.json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: exception.message,
});
}
}
7. 守卫(Guards)
守卫用于处理授权逻辑:
// src/common/guards/auth.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
// 在这里实现你的授权逻辑
return true; // 或 false
}
}
实战示例:创建一个简单的 REST API
让我们创建一个简单的用户管理 API:
// src/users/dto/create-user.dto.ts
import { IsString, IsEmail, MinLength } from 'class-validator';
export class CreateUserDto {
@IsString()
@MinLength(2)
name: string;
@IsEmail()
email: string;
}
// src/users/user.entity.ts
export class User {
id: number;
name: string;
email: string;
}
// src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import { User } from './user.entity';
import { CreateUserDto } from './dto/create-user.dto';
@Injectable()
export class UsersService {
private users: User[] = [];
create(createUserDto: CreateUserDto): User {
const user = {
id: this.users.length + 1,
...createUserDto,
};
this.users.push(user);
return user;
}
findAll(): User[] {
return this.users;
}
findOne(id: number): User {
return this.users.find(user => user.id === id);
}
}
// src/users/users.controller.ts
import { Controller, Get, Post, Body, Param, UseGuards } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { AuthGuard } from '../common/guards/auth.guard';
@Controller('users')
@UseGuards(AuthGuard)
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Post()
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}
@Get()
findAll() {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.usersService.findOne(+id);
}
}
// src/users/users.module.ts
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}
启动应用
在 main.ts
中配置和启动应用:
// src/main.ts
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './common/filters/http-exception.filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// 全局管道
app.useGlobalPipes(new ValidationPipe());
// 全局过滤器
app.useGlobalFilters(new HttpExceptionFilter());
// 启动应用
await app.listen(3000);
console.log(`Application is running on: ${await app.getUrl()}`);
}
bootstrap();
测试 API
使用 curl 或 Postman 测试 API:
# 创建用户
curl -X POST http://localhost:3000/users \
-H "Content-Type: application/json" \
-d '{"name": "John Doe", "email": "john@example.com"}'
# 获取所有用户
curl http://localhost:3000/users
# 获取特定用户
curl http://localhost:3000/users/1
写在最后
本文介绍了 NestJS 的基础概念和核心功能:
- 项目搭建和结构
- 控制器和路由
- 提供者和服务
- 模块化组织
- 中间件和管道
- 异常处理
- 守卫和授权
这些概念构成了 NestJS 应用程序的基础。在下一篇文章中,我们将深入探讨 NestJS 的数据库操作和 TypeORM 集成。
如果觉得这篇文章对你有帮助,别忘了点个赞 👍
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。