Nest (NestJS) 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的开发框架。它利用 JavaScript 的渐进增强的能力,使用并完全支持 TypeScript (仍然允许开发者使用纯 JavaScript 进行开发),并结合了 OOP (面向对象编程)、FP (函数式编程)和 FRP (函数响应式编程)。
在底层,Nest 构建在强大的 HTTP 服务器框架上,例如 Express (默认),并且还可以通过配置从而使用 Fastify !
Nest 在这些常见的 Node.js 框架 (Express/Fastify) 之上提高了一个抽象级别,但仍然向开发者直接暴露了底层框架的 API。这使得开发者可以自由地使用适用于底层平台的无数的第三方模块。
nestcli项目结构
main.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 {}
AppModule是应用程序的根模块,根模块提供了用来启动应用的引导机制,可以包含很多功能模块。
.module文件需要使用@module 装饰器的类,接收ModuleMetadata对象,其中包括四个属性:providers、controllers、imports、exports。
///(alias) Module(metadata: ModuleMetadata): ClassDecorator
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
该对象的属性描述了模块:
| providers | Nest.js注入器实例化的提供者(服务提供者),处理具体的业务逻辑,各个模块之间可以共享 |
| controllers | 此模块定义了必须实例化的控制器集,处理http请求,包括路由控制,向客户端返回响应,将具体业务逻辑委托给providers处理; |
| imports | 导入模块的列表,如果需要使用其他模块的服务,需要通过这里导入 |
| exports | 提供导出功能,供其他模块导入使用 |
app.module.ts引入了app.controller.ts和app.service.ts文件
app.service.ts
@Injectable()装饰器附加元数据,该元数据声明AppService 是一个可以由Nest IoC容器管理的类。
// app.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
app.controller.ts
@Controller 装饰器 定义了控制器,@Get是请求方法的装饰器,对getHello方法进行装饰,表示这个方法会被get请求调用
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
请求相关
上面的app.controller.ts内容
通过路径localhost:3000
可以直接访问到上面app.controller.ts 的getHello方法
访问的路径是 @Controller/@Get()
例如
@Controller('test')
export class testController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
@Get("Hello")
Hello(): string {
return this.appService.getHello();
}
}
可以通过localhost:3000/test 访问getHello
通过localhost:3000/test 访问Hello
除了get请求还有@Post 等装饰器可以使用
Nest为所有标准HTTP方法提供了装饰器:@Get(), @Post(), @Put(), @Delete(), @Patch(), @Options(), and @Head()。此外,@All()定义了一个处理所有这些事件的端点
nestjs的序列化功能
使用内置的方法,请求返回一个js对象或者数组,它会自动的序列化为JSON结构。
当它返回的是js的原始类型(例如:string, number, boolean等),直接返回该值,将不会序列化这个值
请求相关的其他装饰器
在需要获取客户端请求的详细信息,nest默认是使用Express去获取的 通过添加@Req()装饰器来指示Nest注入请求对象,从而获取请求对象信息
request 对象表示HTTP请求,并具有用于请求查询字符串、参数、HTTP头和正文的属性(等等内容 并不一定需要去手动抓取所需的信息,可以使用提供的专门的装饰器如@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也支持基于路径的模式匹配。例如,星号用作通配符,可以匹配任意字符组合。
@Get('ab*cd')
findAll() {
return 'This route uses a wildcard';
}
“abcd”路由路径将匹配abcd、ab_cd、abecd等。字符?、+、 和()可用于路由路径中,并且是其正则表达式对应项的子集。连字符(-)和点(.)由基于字符串的路径按字面解释。
响应状态码
一般响应状态码都是200,POST请求除外,POST请求是201。可以通过@@HttpCode装饰器进行设置
@Post()
@HttpCode(204)
create() {
return 'This action adds a new cat';
}
设置响应头
如果需要自定义的响应头,可以使用@Header()装饰器,也可以使用图书馆模式的@Res(),去修改响应头(如:res.header())
@Post()
@Header('Cache-Control', 'none')
create() {
return 'This action adds a new cat';
}
重定向
针对指定的URL期望重定向相应,可以通过@Redirect() 装饰器 或者指定库的返回对象(例如使用res.rediect())
@Redirect()必须有两个入参,一个是url,第二个http状态码默认是302
@Get()
@Redirect('https://nestjs.com', 301)
有的时候,需要动态去进行相应HTTP状态码或者去重定向页面,此时接口return返回的值会覆盖掉@Redirect() 装饰器任何的参数
@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
if (version && version === '5') {
return { url: 'https://docs.nestjs.com/v5/' };
}
}
路由参数
在需要对请求路径的参数进行动态配置时,静态路由将不起作用。
此时可以使用@Get() 装饰器去声明。通过这个方式声明的参数可以是使用@Param() 装饰器去获取参数
@@filename()
@Get(':id')
findOne(@Param() params): string {
console.log(params.id);
return `This action returns a #${params.id} cat`;
}
@@switch
@Get(':id')
@Bind(Param())
findOne(params) {
console.log(params.id);
return `This action returns a #${params.id} cat`;
}
子路由域名
@Controller() 装饰器可以设置host参数去要求传入的请求的HTTP主机符合某个特定的值
同时host的内容也可以进行动态的匹配
@Controller({ host: ':account.example.com' })
export class AccountController {
@Get()
getInfo(@HostParam('account') account: string) {
return account;
}
}
host动态匹配:account ,通过@HostParam('account')去获取这个动态的值
nestcli创建文件指令
// nest g [文件类型] [文件名] [文件目录(src目录下)]
// 在home目录下,创建user.service.ts
nest g service user home