基于 Node.js 的后端框架:NestJS 和 Express(二)
在上篇:基于 Node.js 的后端框架(一)中,我们讨论了NestJS 和 Express 的差异以及选择的考量。现在,让我们深入了解一下各自的特点和使用方法,并推荐了学习资源。
一、Express
Express 是基于 Node.js 平台的轻量级 Web 应用框架,它简化了原生 Node.js 开发 HTTP 服务器的复杂度,提供了简洁的 API 和丰富的功能,是 Node.js 生态中最流行的后端框架之一。其设计哲学是“少即是多”,核心专注于 HTTP 路由和中间件,同时保持高度灵活,允许开发者根据需求自由扩展。
1、Express 的特点
-
轻量灵活
核心代码简洁,仅提供基础的 Web 开发功能(路由、中间件、请求处理等),不强制绑定特定的数据库或模板引擎,开发者可按需选择工具栈。 -
强大的路由系统
支持基于 HTTP 方法(GET/POST/PUT/DELETE 等)和 URL 路径的路由定义,可轻松实现 RESTful API 设计。 -
中间件机制
这是 Express 的核心特性。中间件是一个函数,可访问请求对象(req
)、响应对象(res
)和下一个中间件函数(next
),用于处理请求、响应、错误捕获、日志记录等。支持串联多个中间件,形成处理流水线。 -
简化的请求/响应处理
封装了原生 Node.js 的http
模块,提供更直观的 API(如res.send()
、res.json()
、req.params
等),简化参数解析、响应发送等操作。 -
丰富的生态
社区提供了大量第三方中间件(如解析 JSON 数据的body-parser
、处理跨域的cors
、身份验证的passport
等),可快速扩展功能。
2、功能与使用示例
1. 基本使用流程
// 1. 安装:npm install express
const express = require('express');
const app = express(); // 创建应用实例// 2. 定义路由(处理 GET 请求)
app.get('/', (req, res) => {res.send('Hello Express!'); // 发送响应
});// 3. 启动服务器
const port = 3000;
app.listen(port, () => {console.log(`服务器运行在 http://localhost:${port}`);
});
2. 功能示例
-
路由与参数:支持动态路由参数和查询字符串解析
// 动态路由(如 /user/123) app.get('/user/:id', (req, res) => {const userId = req.params.id; // 获取路由参数const name = req.query.name; // 获取查询参数(如 ?name=xxx)res.json({ id: userId, name: name || 'Guest' }); });
-
中间件使用:例如日志中间件、静态文件服务
// 自定义日志中间件 const logger = (req, res, next) => {console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);next(); // 调用下一个中间件 };// 应用中间件(所有请求都会经过) app.use(logger);// 内置中间件:处理 JSON 请求体 app.use(express.json());// 静态文件服务(访问 /public 下的文件) app.use('/public', express.static('static-files'));
-
处理 POST 请求:配合中间件解析请求体
// 解析表单数据(x-www-form-urlencoded) app.use(express.urlencoded({ extended: true }));app.post('/login', (req, res) => {const { username, password } = req.body; // 获取 POST 数据res.send(`登录信息:${username} / ${password}`); });
3、适用场景
- 构建 RESTful API:快速设计和实现数据接口(如前后端分离的后端服务)。
- Web 应用开发:配合模板引擎(如 EJS、Pug)实现服务器端渲染(SSR)。
- 中间层服务:作为代理服务器,转发请求、处理跨域或数据转换。
- 微服务组件:在分布式系统中作为轻量服务节点。
4、生态与扩展
Express 本身仅提供基础功能,但其生态丰富,可通过中间件快速扩展:
- 数据解析:
express.json()
(内置)、multer
(处理文件上传)。 - 跨域处理:
cors
中间件。 - 身份验证:
passport.js
、jsonwebtoken
(JWT 认证)。 - 数据库集成:配合
mongoose
(MongoDB)、sequelize
(SQL 数据库)等 ORM 工具。 - API 文档:
swagger-ui-express
自动生成接口文档。
附:学习资源
- 官方文档:Express 中文文档(权威、简洁,含快速入门和 API 参考)。
- 实战教程:
- MDN Express 教程(结合实例讲解核心概念)。
- Express 实战项目(开源的“真实世界”博客 API 实现)。
二、NestJS
NestJS 是一个基于 Node.js 的企业级后端框架,由 Kamil Myśliwiec 于 2017 年创建。它借鉴了 Angular 的模块化架构思想,结合了面向对象编程(OOP)、函数式编程(FP)和函数式响应式编程(FRP)的特点,旨在为 Node.js 开发提供结构化、可扩展、易维护的解决方案。
与 Express 的“轻量灵活”不同,NestJS 更强调“规范与架构”,尤其适合大型团队协作和复杂业务系统的开发。
1、特点
-
TypeScript 优先
原生支持 TypeScript(也兼容 JavaScript),通过静态类型检查提升代码质量,减少运行时错误,同时增强 IDE 智能提示,提升开发效率。 -
模块化架构
采用“模块(Module)”作为组织代码的基本单元,每个模块封装一组相关的控制器、服务和依赖,形成高内聚低耦合的结构。这种设计让大型项目的代码组织更清晰。 -
依赖注入(DI)
内置依赖注入系统,通过控制反转(IoC)管理组件间的依赖关系,简化代码测试、复用和维护。例如,服务(Service)可以被注入到控制器(Controller)中,无需手动实例化。 -
灵活的底层适配
默认使用 Express 作为 HTTP 服务器,也可无缝切换到 Fastify(性能更优的 Node.js 服务器),兼顾兼容性和性能需求。 -
丰富的装饰器
通过装饰器(Decorator)简化路由定义、中间件绑定、管道验证等操作,语法简洁且语义清晰(类似 Spring Boot 的注解)。 -
全栈扩展能力
不仅支持 RESTful API,还内置对 GraphQL、WebSocket、微服务(通过 gRPC、MQTT 等)的支持,可轻松构建复杂分布式系统。
2、概念及代码示例
NestJS 的核心概念围绕“模块-控制器-服务”三层架构展开:
1. 模块(Module)
用于组织相关组件,声明控制器、服务和依赖项。
// 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 {}
2. 控制器(Controller)
负责处理 HTTP 请求,定义路由和请求处理逻辑(类似 Express 的路由处理器)。
// src/app.controller.ts
import { Controller, Get, Param } from '@nestjs/common';
import { AppService } from './app.service';@Controller() // 基础路由(此处为空,即根路径)
export class AppController {// 通过依赖注入获取 AppService 实例constructor(private readonly appService: AppService) {}@Get() // 处理 GET / 请求getHello(): string {return this.appService.getHello(); // 调用服务的方法}@Get('/user/:id') // 处理 GET /user/:id 请求getUser(@Param('id') id: string): string {return this.appService.getUser(id);}
}
3. 服务(Service)
封装业务逻辑,被控制器调用,可通过依赖注入复用(类似“业务逻辑层”)。
// src/app.service.ts
import { Injectable } from '@nestjs/common';@Injectable() // 标记为可注入的服务
export class AppService {getHello(): string {return 'Hello NestJS!';}getUser(id: string): string {return `User ID: ${id}`;}
}
4. 启动应用
// src/main.ts
import { NestFactory } from '@nestjs/common';
import { AppModule } from './app.module';async function bootstrap() {const app = await NestFactory.create(AppModule); // 创建应用实例await app.listen(3000); // 启动服务器,监听 3000 端口console.log(`应用运行在 http://localhost:3000`);
}
bootstrap();
3、进阶特性
- 中间件(Middleware):类似 Express 中间件,用于处理请求(如日志、认证),可全局或局部应用。
- 管道(Pipe):用于数据验证和转换(如参数校验、类型转换),内置
ValidationPipe
可配合 class-validator 实现自动校验。 - 守卫(Guard):控制路由访问权限(如身份验证、角色权限),在控制器或路由执行前生效。
- 拦截器(Interceptor):拦截请求/响应,实现日志记录、缓存、异常处理等(如统一响应格式)。
- 微服务:通过
@nestjs/microservices
模块支持多种通信协议(gRPC、RabbitMQ 等),适合构建分布式系统。
4、适用场景
- 企业级应用:大型业务系统(如电商后台、CRM、ERP),需要严格的架构规范和可扩展性。
- 微服务架构:通过内置的微服务模块快速搭建分布式服务集群。
- API 开发:高效构建 RESTful API 或 GraphQL 接口,配合管道和守卫简化验证与权限控制。
- 团队协作项目:模块化和依赖注入减少代码冲突,提升协作效率。
5、生态与工具
- CLI 工具:
@nestjs/cli
提供项目初始化、代码生成(控制器、服务等)、启动调试等功能,简化开发流程。 - 数据库集成:支持 TypeORM、Prisma、Mongoose 等 ORM/ODM 工具,轻松连接 SQL/NoSQL 数据库。
- 认证授权:
@nestjs/passport
集成 Passport.js,支持 JWT、OAuth2 等认证策略。 - 文档生成:
@nestjs/swagger
自动生成 Swagger API 文档,方便接口管理。
附:学习资源
- 官方文档:NestJS 中文文档(结构清晰,含快速入门和深度指南)。
- 实战教程:
- NestJS 官方示例项目(涵盖 REST、GraphQL、微服务等场景)。
- NestJS 实战博客 API(符合 RealWorld 规范的博客后端)。