Nest.js 简介
Nest.js 是一个用 TypeScript 构建高效、可扩展的服务器端应用程序的框架。它结合了 TypeScript 的优势和 Angular 的设计理念,提供了一种优雅而强大的开发体验。Nest.js 基于模块化的架构,拥有强大的依赖注入、模块化、和可测试性等特性,使得构建复杂的应用程序变得更加容易。
安装 Nest.js CLI
要开始使用 Nest.js,首先需要安装 Nest.js 的命令行工具(CLI)。可以通过以下命令进行安装:
npm install -g @nestjs/cli
安装完成后,我们就可以使用 nest
命令来创建新的 Nest.js 项目了。
创建 Nest.js 项目
通过以下命令创建一个新的 Nest.js 项目:
nest new project-name
这将在当前目录下创建一个名为 project-name
的新项目,并自动初始化一些基本的文件和配置。
目录结构
目录结构很简洁,在创建项目之后,目前只有一个根模块(App
),后续会创建出很多各种模块 User/Order/...
等等,NestJS
可以说是通过"模块"来管理整个应用的。
文件名 | 描述 |
---|---|
main.ts | 入口文件,后续全局性的配置会在这里配置。 |
app.controller.ts | 定义接口的地方,前端请求过来,最先到达这里。 |
app.module.ts | 应用的根模块,后续会创建很多模块,都要在此进行管理 |
app.service.ts | 管理数据库的 CRUD 操作 |
app.controller.spec.ts | 单元测试,不用管它。 |
Nestjs的控制器Controller
@Controller()
装饰器,这是定义基本控制器所必需的。该装饰器可以传入一个路径参数,作为访问这个控制器的主路径(不传则表示默认路径)
请求对象
处理程序通常要访问客户端请求的详细信息。通过将 @Req()
装饰器添加到处理程序的签名来指示 Nest 注入它来访问请求对象。
import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';
@Controller('user')
export class UserController {
@Get()
getHello(@Req() request: Request): string {
console.log(request);
return 'Hello Nest.js!';
}
}
请求对象表示 HTTP 请求,并具有请求查询字符串、参数、HTTP 标头和正文的属性等。在大多数情况下,没有必要手动获取这些属性。我们可以使用开箱即用的专用装饰器,例如 @Body() 或 @Query()。下面是提供的装饰器列表和它们代表的普通平台特定对象。
@Request(), @Req() | req |
@Response(), @Res()* | res |
@Next() | next |
@Session() | req.session |
@Param(key?: string) | req.params / req.params[key] |
@Body(key?: string) | req.body / req.body[key] |
@Query(key?: string) | req.query / req.query[key] |
@Headers(name?: string) | req.headers / req.headers[name] |
@Ip() | req.ip |
@HostParam() | req.hosts |
资源
Nest 为所有标准的 HTTP 方法提供装饰器:@Get()、@Post()、@Put()、@Delete()、@Patch()、@Options() 和 @Head()。此外,@All() 定义了一个端点来处理所有这些。
import { Controller, Delete, Get, Patch, Post, Put } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
// 匹配到 get 请求 http://localhost:3000
@Get()
getHello(): string {
return this.appService.getHello();
}
// 匹配到 get 请求 http://localhost:3000/list
@Get('/list')
getHelloList(): string {
return '这是list页面';
}
// 匹配到 post 请求 http://localhost:3000/list
@Post('/list')
create(): string {
return 'post请求页面';
}
// 匹配到 put 请求 http://localhost:3000/list
@Put('/list')
update(): string {
return 'put请求页面';
}
// 匹配到 delete 请求 http://localhost:3000/list
@Delete('/list')
delete(): string {
return 'delete请求页面';
}
// 匹配到 patch 请求 http://localhost:3000/list
@Patch('/list')
patch(): string {
return 'patch请求页面';
}
}
路由参数
当接受动态数据作为请求的一部分时(例如,GET /cats/1 获取 ID 为 1 的 cat),具有静态路径的路由将不起作用。为了定义带参数的路由,在路由的路径中添加路由参数标记,以捕获请求 URL 中该位置的动态值。使用 @Param()
装饰器访问以这种方式声明的路由参数,应将其添加到方法签名中。
Param参数
@Get(':id')
// 请注意,在params方式获取参数中,必须是@Param(路径参数的名称,需要和:id这个地方保持一致),id:string这部分名称可以随意
getUserInfoByParamId(@Param('id') id: string) {
console.log(id, 'id');
return 'getUserInfoByParamId';
}
Query参数
@Get('/user')
// 请注意:在query方式获取参数中,@Query('id') id: string和@Query() id: string的区别如下:
// @Query() params: any获取的是一个获取所有query参数的解析对象,如{ a: '1', b: '2', c: '3' }
// @Query('id') id: string获取的是query参数中具体的id这个参数的值
// 如下:如果请求的路径是/xxx?a=1&b=2&c=3
getUserInfoByQueryId(@Query() params: any, @Query('a') a: string) {
console.log(params, 'params'); // { a: '1', b: '2', c: '3' }
console.log(a, 'a') // 1
return 'getUserInfoByQueryId';
}
请求负载
我们之前的 POST 路由处理程序不接受任何客户端参数。遇到这种问题怎么办呢?我们可以使用 @Body()
装饰器来解决。
但首先我们需要确定 DTO(数据传输对象)架构。DTO 是定义数据如何通过网络发送的对象。我们可以通过使用 TypeScript 接口或简单的类来确定 DTO 模式。下面我们来创建一个 CreateCatDto 类:
// create-cat.dto.ts
export class CreateCatDto {
name: string;
age: number;
breed: string;
}
此后,我们可以在 demoController 中使用新创建的 DTO
// demo.controller.ts
import { Body, Controller, Post } from '@nestjs/common';
import { DemoService } from './demo.service';
import { CreateCatDto } from './dto/create-cat.dto';
@Controller('demo')
export class DemoController {
constructor(private readonly demoService: DemoService) {}
@Post('/createUser')
createUser(@Body() createCatDto: CreateCatDto) {
console.log(createCatDto, 'createCatDto');
return 'createCatDto';
}
}
Nestjs的模块Module
模块是用
@Module()
装饰器注释的类。@Module()
装饰器提供 Nest 用于组织应用结构的元数据。至少有一个模块,即根模块。根模块是 Nest 用于构建应用图的起点 - Nest 用于解析模块和提供器关系及依赖的内部数据结构。
@Module()
装饰器采用单个对象,其属性描述模块:
字段 | 功能 |
---|---|
providers | 将由 Nest 注入器实例化并且至少可以在该模块中共享的提供程序 |
controllers | 此模块中定义的必须实例化的控制器集 |
imports | 导出此模块所需的提供程序的导入模块列表 |
exports | 这个模块提供的 providers 的子集应该在导入这个模块的其他模块中可用。你可以使用提供器本身或仅使用其令牌(provide 值) |
输入 nest g resource user
生成一个基础的 CRUD 功能,现在目录结构为:
src
├── user
| ├── dto
| | ├── create-user.dto.ts
| | └── update-user.dto.ts
| |
| ├── entities
| | └── user.entity.ts
| |
| ├── user.controller.spec.ts
| ├── user.controller.ts
| ├── user.module.ts
| └── user.service.ts
|
├── app.module.ts