NestJS - o mesmo back-end real no nodejs

imagem

O NestJS é a estrutura criada para facilitar a vida do desenvolvedor, usando as abordagens arquitetônicas corretas e ditando suas próprias regras.

Portanto, o NestJS não é apenas uma estrutura de back-end, mas também a oportunidade de entrar no mundo de conceitos avançados, como DDD , sourcing de eventos e arquitetura de microsserviços. Tudo é empacotado de maneira simples e fácil, portanto a escolha é sua - se você decide usar a plataforma inteira ou apenas seus componentes.

Primeiro, vou falar sobre a minha experiência. Durante muito tempo, escrevi no ASP.NET, e havia um frontend no AngularJS. Em outubro de 2016, houve uma mudança para Angular e Typcript. E aqui está ele! Digitando no front-end, você pode fazer coisas complexas com bastante facilidade! Antes disso (desenvolvimento em nestjs) no nó, eu o desenvolvia apenas por diversão, e de alguma forma houve até uma tentativa de introduzir boas práticas e texto datilografado no popular Koa . Mas o NestJS ainda é um pouco diferente.

O NestJS, uma estrutura totalmente escrita em TypeScript (também suporta JS, mas os tipos são muito bons), é fácil de testar e contém tudo o que você precisa.

Como criar um aplicativo simples no NestJS?

NestJS tem expresso sob o capô. Quaisquer extensões para express são fáceis de implementar no Nest. Mas este não é o ponto aqui, com um forte desejo expresso pode ser tomado e mudado.

Primeiro, você pode copiar um pequeno kit inicial para si mesmo:

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

Server.ts inclui uma função assíncrona responsável por carregar nosso aplicativo:

 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(); 

Bem, inicie o npm run start e veja o aplicativo na porta 3000.

Do que é feito o NestJS?

O autor do framework foi inspirado nas idéias do Angular, e o NestJS se mostrou muito semelhante ao Angular, especialmente nas versões anteriores.

Controladores

A camada do controlador é responsável pelo processamento de solicitações recebidas e pelo retorno de uma resposta ao cliente. Um exemplo simples de controlador:

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

Fornecedores

Quase tudo é Provedores - Serviço, Repositório, Fábrica, Auxiliar, etc. Eles podem ser implementados em controladores e outros fornecedores. Se você diz a linguagem do Angular - é tudo `@Injectables

Por exemplo, um serviço regular:
 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; } } 

Módulos

Um módulo é uma classe com o decorador Module (). O decorador Module () fornece metadados que o Nest usa para organizar a estrutura do aplicativo. Cada aplicativo Nest possui pelo menos um módulo, o módulo raiz. O módulo raiz é onde o Nest começa a organizar a árvore de aplicativos. De fato, o módulo raiz pode ser o único módulo em seu aplicativo, especialmente quando o aplicativo é pequeno, mas isso não faz sentido. Na maioria dos casos, você terá vários módulos, cada um com um conjunto de recursos intimamente relacionado. No Nest, os módulos são singleton por padrão, para que você possa compartilhar facilmente a mesma instância de componente entre dois ou mais módulos.

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

Um pouco sobre módulos dinâmicos

O sistema modular Nest vem com a função de módulo dinâmico. Isso permite criar módulos personalizados sem nenhum esforço. Vamos dar uma olhada no 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, }; } } 

Ele define o componente Connection por padrão, mas adicionalmente - dependendo das opções e entidades transferidas - cria uma coleção de provedores, por exemplo, componentes do repositório. De fato, o módulo dinâmico expande os metadados do módulo. Esse recurso essencial é útil quando você precisa registrar componentes dinamicamente. Em seguida, você pode importar o DatabaseModule da seguinte maneira:

 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 {} 

A propósito, para trabalhar com o banco de dados, há um TypeORM legal que pode funcionar com a maioria dos bancos de dados.

Middlewares

Middlewares é uma função que é chamada antes do manipulador de rotas. Eles têm acesso a solicitação e resposta. De fato, eles são os mesmos que os expressos .

 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(); }; } } 

Filtros de exceção

O Nest possui uma camada de exceção, responsável por capturar exceções não tratadas e retornar a resposta apropriada ao usuário final.

Cada exceção é manipulada pelo filtro de exceção global e, quando não é reconhecida (não uma HttpException ou uma classe que herda uma HttpException), o usuário recebe a seguinte resposta JSON:

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

Tubos

O pipe deve implementar a interface PipeTransform.
 import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common'; @Injectable() export class ValidationPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { return value; } } 

Pipe converte a entrada no resultado desejado.

Além disso, isso pode passar para validação, pois também é possível para eles lançar uma exceção se os dados estiverem incorretos. Por exemplo:

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

Ou você pode declarar um canal global:

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

Guardas

Os guardas devem implementar a interface CanActivate. Os guardas têm responsabilidade exclusiva. Eles determinam se a solicitação deve ser processada pelo manipulador de rotas ou não.

 @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 {} 

Interceptores

Os interceptores têm vários recursos úteis inspirados na técnica de Programação Orientada a Aspectos (AOP). Eles permitem que você:

  • vincular lógica adicional antes / depois da execução do método;
  • converte o resultado retornado pela função;
  • Converter uma exceção lançada de uma função
  • redefina completamente a função dependendo das condições selecionadas (por exemplo, para armazenamento em cache).

Microsserviços

O Nest Microservice é apenas um aplicativo que usa uma camada de transporte diferente (não HTTP).

O Nest suporta dois tipos de comunicação - TCP e Redis pub / sub, mas a nova estratégia de transporte é fácil de implementar implementando a interface CustomTransportStrategy.

Você pode criar facilmente um microsserviço a partir do seu aplicativo:

 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(); 

O Nest Microservice reconhece mensagens por padrões. Um padrão é um valor simples, um objeto, uma sequência ou até um número.

 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); } } 

E para comunicação entre microsserviços, você deve usar o cliente:

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

E aqui será o envio da mensagem:

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

O NestJS e o Angular estão tão intimamente conectados que o autor da estrutura pode ser facilmente visto em conferências e reuniões. Por exemplo, a equipe nrwl incluiu recentemente o modelo nestjs em seu nx.

 ng g node-app nestjs-app -framework nestjs 

O NestJS já está maduro o suficiente e muitas empresas já o estão usando.
Quem está usando o NestJS na produção agora?

A estrutura em si: https://github.com/nestjs/nest

Muitos links legais aqui: Awesome-nestjs
Comunidade de língua russa do NestJS em um telegrama https://t.me/nest_ru
Relatório em russo sobre o NestJS.

E, claro, assine o canal no telegrama @ngFanatic , onde há notícias sobre o NestJS e o Angular.

PS: Isso é apenas parte dos recursos do NestJS; em uma experiência pessoal de um ano, haverá um artigo separado.

Source: https://habr.com/ru/post/pt439434/


All Articles