初始nestjs

179 阅读5分钟

Nest (NestJS) 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的开发框架。它利用 JavaScript 的渐进增强的能力,使用并完全支持 TypeScript (仍然允许开发者使用纯 JavaScript 进行开发),并结合了 OOP (面向对象编程)、FP (函数式编程)和 FRP (函数响应式编程)。

在底层,Nest 构建在强大的 HTTP 服务器框架上,例如 Express (默认),并且还可以通过配置从而使用 Fastify !

Nest 在这些常见的 Node.js 框架 (Express/Fastify) 之上提高了一个抽象级别,但仍然向开发者直接暴露了底层框架的 API。这使得开发者可以自由地使用适用于底层平台的无数的第三方模块。

nestcli项目结构

nestcli结构.png

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],
})

该对象的属性描述了模块:

providersNest.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

参考文章