nest-learn-day1

6 min read
Table of Contents

1. IoC (控制反转) 与装饰器原理

1.1 IoC (Inversion of Control) 控制反转 / DI (Dependency Injection) 依赖注入

NestJS 的核心设计基于 IoC 容器。

  • 原理:在传统的开发中,如果 UserController 需要使用 UserService,通常需要在 Controller 内部 new UserService()。而在 NestJS 中,控制权被反转了。对象的创建和依赖关系的组装由 Nest IoC 容器(Runtime System)负责,而不是由开发者手动管理。

  • 实现

    1. Provider 定义:通过 @Injectable() 装饰器将 UserService 标记为可被注入的服务。
    2. Module 注册:在 UserModuleAppModuleproviders 数组中注册该服务。
    3. 构造器注入:在 UserController 的构造函数中声明依赖类型,Nest 运行时会自动查找并注入实例。
    tssrc/user/user.controller.ts
    export class UserController {
    // 这里的 private readonly userService 实际上就是一种简写的依赖注入声明
    constructor(private readonly userService: UserService) {}
    }

1.2 装饰器 (Decorators) 原理

装饰器是 NestJS 的语法糖核心,本质上是 高阶函数,用于在设计阶段为类、方法或属性添加 元数据 (Metadata)

  • 技术基础:依赖于 TS 的 experimentalDecorators 特性和 reflect-metadata 库。
  • 工作流程
    1. 当代码运行时,装饰器函数(如 @Controller, @Get)被执行。
    2. 装饰器通过 Reflect.defineMetadata 将配置信息(如路径路由、HTTP 方法、请求参数位置等)存储在目标对象的原型链上。
    3. NestFactory 在启动时扫描所有注册的 Module,利用反射机制读取这些元数据,从而构建路由映射表和依赖关系图。

2. Controller (控制器) 的使用方式

控制器负责处理传入的 Request 并向客户端返回 Response

2.1 基础定义

使用 @Controller 装饰器定义,可以指定路由前缀和版本。

tssrc/user/user.controller.ts
@Controller({
path: 'user', // 路由前缀,访问路径为 /user
version: '1', // 版本控制,若启用URI版本,访问路径可能为 /v1/user
})
export class UserController { ... }

2.2 响应处理

NestJS 默认使用标准模式:当请求处理函数返回一个 JavaScript 对象或数组时,它会自动序列化为 JSON。

  • 状态码:默认 200 (POST 为 201)。可以使用 @HttpCode(500) 修改。
  • Headers:可以使用 @Header('Cache-Control', 'none') 添加响应头。

3. GET / POST 写法与传参

UserController 中可以看到多种传参方式的实战应用。

3.1 GET 请求与传参

GET 请求通常用于获取数据,参数通过 URL 路径 (Params)查询字符串 (Query) 传递。

  • 查询字符串 (@Queryreq.query): 用于处理如 /user?name=test 的请求。

    typescript
    // 方式一:使用 @Request() 获取底层 Express 对象 (不推荐,耦合了 Express)
    @Get()
    findAll(@Request() req: ExpressRequest) {
    return { message: req.query.name };
    }
    // 方式二:使用 @Query() 装饰器 (推荐,Nest 风格)
    @Get('find')
    findByQuery(@Query('name') name: string) {
    return { message: name };
    }
  • 路径参数 (@Param): 用于处理如 /user/123 的请求。

    typescript
    @Get(':id') // 定义动态路径参数 :id
    findId(@Param('id') id: string) {
    console.log(id);
    return { message: id };
    }

3.2 POST 请求与传参

POST 请求通常用于提交数据,参数通过 请求体 (Body) 传递。

  • 请求体 (@Body): 用于接收 JSON 表单数据。

    typescript
    // 读取 Body 中的特定字段 'age'
    @Post()
    create(@Body('age') body: number) {
    console.log(body);
    return { code: 200, message: body };
    }
    // 读取完整 Body 并使用 DTO (推荐)
    // create(@Body() createUserDto: CreateUserDto) { ... }
  • DTO (Data Transfer Object): 虽然示例代码中部分使用了简单类型,但最佳实践是定义 DTO 类(如 src/user/dto/create-user.dto.ts),结合 ValidationPipe 进行参数验证。

4. Nest CLI 脚手架的使用方法

Nest CLI 是极其强大的生产力工具,遵循 “Convention over Configuration” (约定优于配置) 原则。

4.1 安装与初始化

bashTerminal window
npm i -g @nestjs/cli # 全局安装
nest new project-name # 创建新项目

4.2 常用生成命令 (Generator)

在项目根目录下运行,会自动创建文件并更新 app.module.ts 等文件。

命令简写作用示例
nest generate module [name]nest g mo [name]生成模块nest g mo user
nest generate controller [name]nest g co [name]生成控制器nest g co user
nest generate service [name]nest g s [name]生成服务nest g s user
nest generate resource [name]nest g res [name]生成完整的 CRUD 资源nest g res order

提示:使用 nest g res [name] 是最快的方式,它会一次性生成 Module, Controller, Service, DTO, Entity 并且配置好基本的 CRUD 代码结构。

4.3 运行项目

bashTerminal window
npm run start # 启动
npm run start:dev # 启动并监听文件变化 (开发模式)
npm run start:debug # 调试模式

后记

My avatar

感谢你读到这里。

这座小站更像一份持续维护的“终端笔记”:记录我解决问题的过程,也记录走过的弯路。

如果这篇内容对你有一点点帮助:

  • 点个赞 / 收藏一下,方便你下次回来继续翻
  • 欢迎在评论区补充你的做法(或者指出我的疏漏)
  • 想持续收到更新:可以订阅 RSS(在页面底部)

我们下篇见。


More Posts

评论

评论 (0)

请先登录后再发表评论

加载中...