NestJS-Node.js上的真实后端

图片

NestJS是一种使用正确的架构方法并规定了自己的规则的框架,旨在使开发人员的工作更轻松。

因此,NestJS不仅是一个后端框架,而且是进入高级概念世界(例如DDD事件源和微服务体系结构)的机会。 一切都以简单的方式打包,因此,选择就是您自己-是决定使用整个平台还是仅使用其组件。

首先,我将向您介绍我的经验。 我在ASP.NET上写了很长时间,然后在AngularJS上有了一个前端。 2016年10月,改用Angular和Typescript。 在这里! 在前端输入,您可以轻松完成复杂的事情! 在此之前(在nestjs上进行开发)在节点上,我只是出于娱乐目的而开发了它,并且不知何故甚至尝试将流行的实践和打字稿引入流行的Koa中 。 但是NestJS仍然有些不同。

NestJS,一个完全用TypeScript编写的框架(它也支持JS,但是类型非常好),易于测试,并且包含您需要的所有内容。

如何在NestJS上创建一个简单的应用程序?

NestJS在后台有表达。 express的任何扩展都可以在Nest中轻松实现。 但这不是重点,表达强烈的欲望可以被接受和改变。

首先,您可以向自己复制一个小型入门工具包:

git clone https://github.com/nestjs/typescript-starter.git project 

Server.ts包含一个异步功能,负责加载我们的应用程序:

 import { NestFactory } from '@nestjs/core'; import { ApplicationModule } from './modules/app.module'; async function bootstrap() { const app = await NestFactory.create(ApplicationModule); await app.listen(3000); } bootstrap(); 

好了,然后启动npm run start并在端口3000上看到该应用程序。

NestJS是由什么制成的?

该框架的作者受到Angular思想的启发,而NestJS却与Angular非常相似,尤其是在早期版本中。

控制器

控制器层负责处理传入的请求并将响应返回给客户端。 一个简单的控制器示例:

 import { Controller, Get } from '@nestjs/common'; @Controller('cats') export class CatsController { @Get() findAll() { return []; } } 

提供者

几乎所有内容都是提供者-服务,存储库,工厂,助手等。 它们可以在控制器和其他提供程序中实现。 如果您说的是Angular的语言-全部都是@@ Injectables

例如,常规服务:
 import { Injectable } from '@nestjs/common'; import { Cat } from './interfaces/cat.interface'; @Injectable() export class CatsService { private readonly cats: Cat[] = []; create(cat: Cat) { this.cats.push(cat); } findAll(): Cat[] { return this.cats; } } 

模组

模块是具有Module ()装饰器的类。 Module ()装饰器提供Nest用来组织应用程序结构的元数据。 每个Nest应用程序都有至少一个模块,即根模块。 根模块是Nest开始组织应用程序树的地方。 实际上,根模块可能是应用程序中唯一的模块,尤其是在应用程序较小的情况下,但这没有任何意义。 在大多数情况下,您将有几个模块,每个模块都有一组密切相关的功能。 在Nest中,默认情况下模块是单例的,因此您可以轻松地在两个或多个模块之间共享同一组件实例。

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

关于动态模块的一些知识

Nest模块化系统具有动态模块功能。 这使您可以轻松创建自定义模块。 让我们看一下DatabaseModule:

 import { Module, DynamicModule } from '@nestjs/common'; import { createDatabaseProviders } from './database.providers'; import { Connection } from './connection.component'; @Module({ components: [Connection], }) export class DatabaseModule { static forRoot(entities = [], options?): DynamicModule { const providers = createDatabaseProviders(options, entities); return { module: DatabaseModule, components: providers, exports: providers, }; } } 

默认情况下,它定义了Connection组件,但另外(取决于传输的选项和​​实体)创建了提供程序的集合,例如存储库组件。 实际上,动态模块扩展了该模块的元数据。 当您需要动态注册组件时,此基本功能很有用。 然后,您可以按以下方式导入DatabaseModule:

 import { Module } from '@nestjs/common'; import { DatabaseModule } from './database/database.module'; import { User } from './users/entities/user.entity'; @Module({ imports: [ DatabaseModule.forRoot([User]), ], }) export class ApplicationModule {} 

顺便说一下,对于使用数据库,有一个很酷的TypeORM可以与大多数数据库一起使用。

中间件

中间件是在路由处理程序之前调用的函数。 他们有权请求和响应。 实际上,它们与express中的相同。

 import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common'; @Injectable() export class LoggerMiddleware implements NestMiddleware { resolve(...args: any[]): MiddlewareFunction { return (req, res, next) => { console.log('Request...'); next(); }; } } 

异常过滤器

Nest具有一个异常层,负责捕获未处理的异常并将适当的响应返回给最终用户。

每个异常都由全局异常过滤器处理,当无法识别它时(不是HttpException或继承HttpException的类),用户将收到以下JSON响应:

 { "statusCode": 500, "message": "Internal server error" } 

管子

管道必须实现PipeTransform接口。
 import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common'; @Injectable() export class ValidationPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { return value; } } 

管道将输入转换为所需的结果。

此外,这可能会通过验证,因为如果数据不正确,他们也有可能引发异常。 例如:

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

或者,您可以声明全局管道:

 async function bootstrap() { const app = await NestFactory.create(ApplicationModule); app.useGlobalPipes(new ValidationPipe()); await app.listen(3000); } bootstrap(); 

守卫

警卫队必须实现CanActivate接口。 警卫全权负责。 它们确定请求是否应由路由处理程序处理。

 @Injectable() export class RolesGuard implements CanActivate { canActivate( context: ExecutionContext, ): boolean | Promise<boolean> | Observable<boolean> { // const request = context.switchToHttp().getRequest(); // const data = context.switchToWs().getData(); return true; } } : <source lang="javascript"> @Controller('cats') @UseGuards(RolesGuard) export class CatsController {} 

拦截器

拦截器具有许多有用的功能,这些功能受面向方面编程(AOP)技术的启发。 他们允许您:

  • 在执行该方法之前/之后绑定其他逻辑;
  • 转换函数返回的结果;
  • 转换从函数引发的异常
  • 根据所选条件(例如,用于缓存)完全重新定义功能。

微服务

Nest Microservice只是使用其他传输层(而非HTTP)的应用程序。

Nest支持两种通信方式-TCP和Redis pub / sub,但是通过实现CustomTransportStrategy接口,可以轻松实现新的传输策略。

您可以从应用程序轻松创建微服务:

 import { NestFactory } from '@nestjs/core'; import { ApplicationModule } from './modules/app.module'; import { Transport } from '@nestjs/microservices'; async function bootstrap() { const app = await NestFactory.createMicroservice(ApplicationModule, { transport: Transport.TCP, }); app.listen(() => console.log('Microservice is listening')); } bootstrap(); 

Nest Microservice通过模式识别消息。 模式是一个简单的值,一个对象,一个字符串甚至是一个数字。

 import { Controller } from '@nestjs/common'; import { MessagePattern } from '@nestjs/microservices'; @Controller() export class MathController { @MessagePattern({ cmd: 'sum' }) sum(data: number[]): number { return (data || []).reduce((a, b) => a + b); } } 

对于微服务之间的通信,您必须使用客户端:

 @Client({ transport: Transport.TCP, port: 5667 }) client: ClientProxy; 

这是消息的发送:

 @Get() call(): Observable<number> { const pattern = { cmd: 'sum' }; const data = [1, 2, 3, 4, 5]; return this.client.send<number>(pattern, data); } 

NestJS和Angular紧密相连,因此可以在ng会议上轻松看到该框架的作者。 例如,nrwl团队最近在其nx中包含了 nestjs模板。

 ng g node-app nestjs-app -framework nestjs 

NestJS已经足够成熟,许多公司已经在使用它。
谁在生产中使用NestJS?

框架本身: https : //github.com/nestjs/nest

这里有很多很酷的相关链接: Awesome-nestjs
NestJS的俄语社区NestJS https://t.me/nest_ru
关于NestJS的俄语报告。

当然,请订阅@ngFanatic电报中的频道,那里有有关NestJS和Angular的新闻。

PS:这只是NestJS功能的一部分,大约一年的个人经验,将另作文章。

Source: https://habr.com/ru/post/zh-CN439434/


All Articles