NestJS est ce cadre créé pour faciliter la vie du développeur, en utilisant les bonnes approches architecturales et en dictant ses propres règles.
Par conséquent, NestJS n'est pas seulement un framework backend, mais aussi l'opportunité d'entrer dans le monde des concepts avancés, tels que
DDD ,
Event sourcing et architecture de microservices. Tout est emballé de manière simple et facile, vous avez donc le choix - que vous décidiez d'utiliser la plate-forme entière ou simplement d'utiliser ses composants.
Tout d'abord, je vais vous parler de mon expérience. Pendant longtemps, j'ai écrit sur ASP.NET, puis il y avait un frontend sur AngularJS. En octobre 2016, il y a eu un passage à Angular et Typescript. Et voilà! En tapant dans le frontend, vous pouvez faire des choses complexes assez facilement! Avant cela (développement sur nestjs) sur le nœud, je l'avais développé uniquement pour le plaisir, et d'une manière ou d'une autre, il y avait même une
tentative d'introduire de bonnes pratiques et de la dactylographie dans le Koa populaire . Mais NestJS est toujours un peu différent.
NestJS, un framework entièrement écrit en TypeScript (il prend également en charge JS, mais les types sont très bons), il est facile à tester et contient tout ce dont vous avez besoin.
Comment créer une application simple sur NestJS?NestJS a express sous le capot. Toutes les extensions pour express sont faciles à implémenter dans Nest. Mais ce n'est pas le sujet ici, avec un fort désir d'exprimer peut être pris et changé.
Tout d'abord, vous pouvez vous copier un petit kit de démarrage:
git clone https://github.com/nestjs/typescript-starter.git project
Server.ts inclut une fonction asynchrone qui est responsable du chargement de notre application:
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();
Eh bien, lancez npm run start et voyez l'application sur le port 3000.
De quoi NestJS est-il fait?L'auteur du cadre a été inspiré par les idées d'Angular, et NestJS s'est avéré être très similaire à Angular, en particulier dans les versions antérieures.
ContrôleursLa couche contrôleur est responsable du traitement des demandes entrantes et du renvoi d'une réponse au client. Un exemple simple de contrôleur:
import { Controller, Get } from '@nestjs/common'; @Controller('cats') export class CatsController { @Get() findAll() { return []; } }
FournisseursPresque tout est fournisseur - Service, référentiel, usine, aide, etc. Ils peuvent être implémentés dans les contrôleurs et autres fournisseurs. Si vous dites la langue d'Angular - c'est tout `@Injectables
Par exemple, un service régulier:
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; } }
ModulesUn module est une classe avec le décorateur
Module (). Le décorateur
Module () fournit des métadonnées que Nest utilise pour organiser la structure de l'application. Chaque application Nest possède au moins un module, le module racine. Le module racine est l'endroit où Nest commence à organiser l'arborescence des applications. En fait, le module racine peut être le seul module de votre application, en particulier lorsque l'application est petite, mais cela n'a pas de sens. Dans la plupart des cas, vous disposerez de plusieurs modules, chacun ayant un ensemble de fonctionnalités étroitement liées. Dans Nest, les modules sont singleton par défaut, vous pouvez donc facilement partager la même instance de composant entre deux modules ou plus.
import { Module } from '@nestjs/common'; import { CatsController } from './cats.controller'; import { CatsService } from './cats.service'; @Module({ controllers: [CatsController], components: [CatsService], }) export class CatsModule {}
Un peu sur les modules dynamiquesLe système modulaire Nest est doté d'une fonction de module dynamique. Cela vous permet de créer des modules personnalisés sans aucun effort. Jetons un coup d'œil au 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, }; } }
Il définit le composant Connexion par défaut, mais en plus - en fonction des options et entités transférées - crée une collection de fournisseurs, par exemple, des composants de référentiel. En fait, le module dynamique développe les métadonnées du module. Cette fonctionnalité essentielle est utile lorsque vous devez enregistrer dynamiquement des composants. Vous pouvez ensuite importer le DatabaseModule comme suit:
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 {}
Soit dit en passant, pour travailler avec la base de données, il existe un
TypeORM cool qui peut fonctionner avec la plupart des bases de données.
MiddlewaresMiddlewares est une fonction qui est appelée avant le gestionnaire d'itinéraire. Ils ont accès à la demande et à la réponse. En fait, ce sont les mêmes qu'en
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(); }; } }
Filtres d'exceptionNest possède une couche d'exception, qui est chargée de détecter les exceptions non gérées et de renvoyer la réponse appropriée à l'utilisateur final.
Chaque exception est gérée par le filtre d'exception global, et lorsqu'elle n'est pas reconnue (pas une HttpException ou une classe qui hérite d'une HttpException), l'utilisateur reçoit la réponse JSON suivante:
{ "statusCode": 500, "message": "Internal server error" }
PipesPipe doit implémenter l'interface PipeTransform.
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common'; @Injectable() export class ValidationPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { return value; } }
Pipe convertit l'entrée au résultat souhaité.
En outre, cela peut passer pour la validation, car il est également possible pour eux de lever une exception si les données sont incorrectes. Par exemple:
@Post() @UsePipes(new ValidationPipe(createCatSchema)) async create(@Body() createCatDto: CreateCatDto) { this.catsService.create(createCatDto); }
Ou vous pouvez déclarer un canal global:
async function bootstrap() { const app = await NestFactory.create(ApplicationModule); app.useGlobalPipes(new ValidationPipe()); await app.listen(3000); } bootstrap();
GardesLes gardes doivent implémenter l'interface CanActivate. Les gardiens ont l'entière responsabilité. Ils déterminent si la demande doit être traitée par le gestionnaire d'itinéraire ou non.
@Injectable() export class RolesGuard implements CanActivate { canActivate( context: ExecutionContext, ): boolean | Promise<boolean> | Observable<boolean> {
IntercepteursLes intercepteurs ont un certain nombre de fonctionnalités utiles qui sont inspirées de la technique de programmation orientée aspect (AOP). Ils vous permettent de:
- lier une logique supplémentaire avant / après l'exécution de la méthode;
- convertir le résultat renvoyé par la fonction;
- Convertir une exception levée à partir d'une fonction
- redéfinissez complètement la fonction en fonction des conditions sélectionnées (par exemple, pour la mise en cache).
MicroservicesNest Microservice est juste une application qui utilise une couche de transport différente (pas HTTP).
Nest prend en charge deux types de communication - TCP et Redis pub / sub, mais la nouvelle stratégie de transport est facile à mettre en œuvre en implémentant l'interface CustomTransportStrategy.
Vous pouvez facilement créer un microservice à partir de votre application:
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 reconnaît les messages par des modèles. Un modèle est une valeur simple, un objet, une chaîne ou même un nombre.
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); } }
Et pour la communication entre microservices, vous devez utiliser le client:
@Client({ transport: Transport.TCP, port: 5667 }) client: ClientProxy;
Et voici l'envoi du message:
@Get() call(): Observable<number> { const pattern = { cmd: 'sum' }; const data = [1, 2, 3, 4, 5]; return this.client.send<number>(pattern, data); }
NestJS et Angular sont si étroitement liés que l'auteur du framework peut être facilement vu lors des conférences et réunions. Par exemple, l'équipe nrwl a récemment
inclus le modèle nestjs dans son nx.
ng g node-app nestjs-app -framework nestjs
NestJS est déjà suffisamment mature et de nombreuses entreprises l'utilisent déjà.
Qui utilise NestJS en production en ce moment?Le cadre lui-même:
https://github.com/nestjs/nestDe nombreux liens sympas ici:
Awesome-nestjsCommunauté russophone de NestJS dans un télégramme
https://t.me/nest_ruRapport en langue russe sur NestJS.Et bien sûr, abonnez-vous à la chaîne dans le télégramme
@ngFanatic où il y a des nouvelles sur NestJS et Angular.
PS: Ce n'est qu'une partie des capacités de NestJS, à propos d'une expérience personnelle d'un an, il y aura un article séparé.