您的位置:首页 > Web前端 > JavaScript

Nest.js的基本概念整理

2020-03-06 20:52 3663 查看

一个基于node.js的后端框架,官方对他的描述如下


完美支持 Typescript

面向 AOP 编程

支持 Typeorm

高并发,异步非阻塞 IO

Node.js 版的 spring

构建微服务应用


下面是对Nest.js的一些基本概念整理,详情还需要查看手册,此处只简略记录对应概念,用法示例代码

一、环境的安装

1、安装nest.js命令

npm install -g @nestjs/cli


2、创建一个项目

nest new project-name


二、controller的概念

controller负责处理传入的请求和向客户端返回响应

controller通过装饰器的形式注册路由,路由支持通配符

import {controller, Get, Post } from '@nestjs/common';
@controller('cats')
export class CatsController {
@Get()
findAll () {
// 此处返回对象则会响应成json,字符串则原样输出
return {}
}
@Get(':id')
show ( @Request() request: Request ) { // 支持依赖注入
}
/*支持注入的依赖有以下这些
@Request()req
@Response()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]
@HttpCode(204)
*/
}


以下是完整实例代码


import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';
@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }
  @Get()
  findAll(@Query() query: ListAllEntities) {
    return `This action returns all cats (limit: ${query.limit} items)`;
  }
  @Get(':id')
  findOne(@Param('id') id: string) {
    return `This action returns a #${id} cat`;
  }
  @Put(':id')
  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
    return `This action updates a #${id} cat`;
  }
  @Delete(':id')
  remove(@Param('id') id: string) {
    return `This action removes a #${id} cat`;
  }
}


控制器准备好了之后,要加入到模块中

// app.module.ts
import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
@Module({
  controllers: [CatsController],
})
export class AppModule {}


三、提供者providers的概念

提供服务者,可用来封装业务逻辑,并且注入到controller

需要用@Injecable()来装饰,表示可注入

可基于属性注入,和controller一样,需要注入到Module中


import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';
@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}



四、模块Module的概念

模块是整个应用的提供者,也是controller,providers的组织者,至少有一个模块,称之为根模块

@module() 装饰器接受一个描述模块属性的对象:

providers 由 Nest 注入器实例化的提供者,并且可以至少在整个模块中共享

controllers 必须创建的一组控制器

imports 导入模块的列表,这些模块导出了此模块中所需提供者

exports 由本模块提供并应在其他模块中可用的提供者的子集。


五、中间件Middleware的概念

类似于express的中间件,支持各种依赖注入,支持next: Function注入

中间件不能在 @Module() 装饰器中列出。我们必须使用模块类的 configure() 方法来设置它们。包含中间件的模块必须实现 NestModule 接口.


示例代码

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}


全局中间件

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);


六、异常过滤器


1、定义异常过滤器

Catch()
export class HttpExceptionFilter implements ExceptionFilter {
}


2、绑定异常过滤器

@useFilters(HttpExceptionFilter)
@Controller('cats')
export class CatsController {
}


七、管道 Pipe的概念


具有@Injectable()装饰器的类,必须实现PipeTransform接口

可用来做参数验证和参数转换


管道类的定义

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}


value是参数的值

metadata元数据

metadata: { type: 'body', metatype: String, data}


绑定管道示例代码

@Post()
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}


对应管道收到的传参为

value: createCatDto

metadata: {

type: 'body',

data: undefined,

metatype: CreateCatDto

}


八、守卫 Guard的概念

具有@Injectable()装饰器的类,必须实现CanActivate接口,用于根据指定条件,判断请求是否由路由处理程序处理

守卫返回true/false,false的话会抛出UnauthorizedException异常


定义守卫示例代码

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
import { Reflector } from '@nestjs/core';
@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}
  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    const hasRole = () => user.roles.some((role) => roles.includes(role));
    return user && user.roles && hasRole();
  }
}


绑定守卫示例代码(可以在controller层,也可以在action层)

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}


九、拦截器 Interceptors 的概念

具有@Injectable()装饰器的类,必须实现NestInterceptor接口

可用来在函数执行前/后绑定额外的逻辑


定义拦截器示例代码


import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');
    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}

使用拦截器示例代码(也可以直接在方法级别使用)

@UseInterceptors(LoggingInterceptor)
export class CatsController {}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Nest.js