1. NestJS 简介
NestJS 由 Kamil Mysliwiec 于 2016 年创立,是一个开源的 Node.js 后端框架。它结合了面向对象编程(OOP)、函数式编程(FP)和函数响应式编程(FRP)的思想,并且内置对 TypeScript 的支持,提供了高度的可扩展性与可维护性。
受 Angular 启发:NestJS 的设计理念与 Angular 类似,使用依赖注入(Dependency Injection)与模块化概念,简化了复杂业务逻辑的拆分和组合。
基于 Express(或 Fastify) :默认使用 Express.js 作为 HTTP 服务器,但也可以轻松切换到性能更佳的 Fastify。
易于上手:拥有活跃的社区和完善的文档,对于新手和资深开发者都非常友好。
如果你之前的技术栈是Springboot 或者 Springcloud,你会比较容易接受nest.js框架的编码模式。
2. 创建基础项目
2.1 安装 Nest CLI
如果你想快速创建一个新的 NestJS 项目并进行开发,官方推荐使用 Nest CLI 工具。可执行以下命令安装:
npm i -g @nestjs/cli
2.2 创建新项目
安装完 CLI 之后,可以使用如下命令快速创建并启动一个新项目:
nest new my-nest-project
cd my-nest-project
npm run start
执行 npm run start 后,你就可以在浏览器中访问 http://localhost:3000,测试基本的「Hello World」接口。
3. 核心概念快速回顾
模块(Module) :用于组织和管理控制器(Controller)、服务(Provider/Service)、以及其他组件。每个模块可以看作是一个业务功能或领域的集合。
控制器(Controller) :负责处理路由请求和响应,类似于 MVC 架构中的“C”。
提供者(Provider/Service) :主要用于编写业务逻辑,可被控制器或其他服务注入(DI)使用。
依赖注入(DI) :通过在构造函数参数中声明需要的依赖(服务),NestJS 会自动实例化并注入。
4. 基础 GET 请求示例
以下示例展示了一个最简单的 GET 请求处理方式,返回「Hello World」字符串。
import { Controller, Get } from '@nestjs/common';
@Controller('hello')
export class HelloController {
@Get()
getHello(): string {
return 'Hello World!';
}
}
@Controller('hello'):将该控制器的访问路径定义为 /hello。
@Get():声明此方法处理对 /hello 路径的 GET 请求。
getHello():返回一个字符串,可以在浏览器或工具(如 Postman)中通过 GET /hello 查看。
4.1 补充:在服务中处理逻辑
一般情况下,我们会将业务逻辑放到服务(Service)里,以便更好的维护和测试。示例:
// hello.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class HelloService {
getHelloMessage(): string {
return 'Hello World from Service!';
}
}
// hello.controller.ts
import { Controller, Get } from '@nestjs/common';
import { HelloService } from './hello.service';
@Controller('hello')
export class HelloController {
constructor(private readonly helloService: HelloService) {}
@Get()
getHello(): string {
return this.helloService.getHelloMessage();
}
}
HelloService 通过 @Injectable() 装饰器表明它可以被依赖注入。
在 HelloController 的构造函数中通过 private readonly helloService: HelloService 注入服务实例。
这样可以更加清晰地划分控制器(处理请求)和服务(处理业务逻辑)的责任。
5. 基础 POST 请求示例
下面我们展示如何处理一个最简单的 POST 请求,并获取请求体中的数据。
import { Controller, Post, Body } from '@nestjs/common';
class CreateMessageDto {
content: string;
submittedBy: string;
}
@Controller('messages')
export class MessagesController {
@Post()
createMessage(@Body() message: CreateMessageDto): CreateMessageDto {
console.log('收到的数据:', message);
// 实际场景中,你可能会将这个信息写入数据库,或做其他业务处理
return message; // 简单地把消息再原样返回
}
}
@Controller('messages'):将控制器路径设为 /messages。
@Post():声明此方法处理对 /messages 的 POST 请求。
@Body():装饰器从请求体中提取 JSON 数据,并自动转换为 CreateMessageDto 的实例。
5.1 补充:结合服务和数据库
在真实项目中,你可能需要将数据写入数据库。以下是简单示例:
// messages.service.ts
import { Injectable } from '@nestjs/common';
interface Message {
content: string;
submittedBy: string;
id: number;
}
@Injectable()
export class MessagesService {
private messages: Message[] = [];
private idCounter = 1;
create(message: Omit<Message, 'id'>): Message {
const newMessage: Message = { ...message, id: this.idCounter++ };
this.messages.push(newMessage);
return newMessage;
}
findAll(): Message[] {
return this.messages;
}
}
// messages.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common';
import { MessagesService } from './messages.service';
interface CreateMessageDto {
content: string;
submittedBy: string;
}
@Controller('messages')
export class MessagesController {
constructor(private readonly messagesService: MessagesService) {}
@Post()
create(@Body() messageDto: CreateMessageDto) {
return this.messagesService.create(messageDto);
}
@Get()
findAll() {
return this.messagesService.findAll();
}
}
MessagesService 中维护了一个内存数组 messages,并提供 create 和 findAll 方法来操作数据。
MessagesController 中注入 MessagesService,通过 create 方法处理 POST 请求,通过 findAll 方法处理 GET 请求。
这样就完成了一个非常简易的「消息」管理功能:
POST /messages:创建消息
GET /messages:查看所有消息
6. 补充更多常见场景示例
6.1 获取路径参数和查询参数
在大多数业务中,除了请求体外,还会常用到“路径参数(Path Parameters)”和“查询参数(Query Parameters)”。
import { Controller, Get, Param, Query } from '@nestjs/common';
@Controller('users')
export class UsersController {
// GET /users/123
@Get(':id')
findOne(@Param('id') id: string) {
return `用户的 ID 为:${id}`;
}
// GET /users/search?keyword=Nest
@Get('search')
search(@Query('keyword') keyword: string) {
return `搜索关键字为:${keyword}`;
}
}
@Param('id'):获取路由定义中的 :id 部分的值。
@Query('keyword'):获取查询参数 keyword 的值。
6.2 PUT 和 DELETE 示例
在 RESTful API 中,常常需要更新或删除数据,可使用 @Put() 和 @Delete() 装饰器。
import { Controller, Put, Delete, Param } from '@nestjs/common';
@Controller('articles')
export class ArticlesController {
// PUT /articles/10
@Put(':id')
updateArticle(@Param('id') id: string): string {
// 这里你可能会根据 id 更新数据库中的文章
return `更新了文章,ID 为:${id}`;
}
// DELETE /articles/10
@Delete(':id')
deleteArticle(@Param('id') id: string): string {
// 这里你可能会根据 id 删除对应的文章
return `删除了文章,ID 为:${id}`;
}
}
7. 结语
通过上述示例,我们展示了在 NestJS 中实现常见的 GET、POST、PUT、DELETE 请求的基本方式,以及如何获取路径参数和查询参数。若要将这些示例投入实际生产项目,通常还需要结合以下内容:
数据库集成:如使用 TypeORM、Prisma 等ORM框架操作数据库。
验证与管道(Validation & Pipes) :如使用 class-validator 和 class-transformer 对请求数据进行验证。
中间件和拦截器(Middleware & Interceptors) :如日志记录、异常处理、认证和授权(JWT/Passport)等。
微服务(Microservices) :NestJS 也提供了内置的微服务支持,可以更好地处理分布式应用场景。
NestJS 提供了清晰的结构和强大的依赖注入机制,使得项目的可维护性和可扩展性大大提高。
作者:Y11_推特同名
链接:https://juejin.cn