Cet article vous fera découvrir l'architecture AOP de Nodele framework back-end Nest.js et présentera les avantages de l'architecture AOP Nest.js. J'espère qu'il sera utile à tout le monde !
Nest.js est un framework back-end Nodejs Il encapsule des plateformes http telles qu'express pour résoudre des problèmes d'architecture. Il fournit MVC, IOC, AOP et d'autres fonctionnalités architecturales qu'Express n'a pas, ce qui rend le code plus facile à maintenir et à développer.
Que signifient ici MVC, IOC et AOP ? Jetons-les respectivement :
MVC est l'abréviation de Model View Controller. Sous l'architecture MVC, la requête est d'abord envoyée au Contrôleur, qui envoie le Service de la couche Modèle pour compléter la logique métier, puis renvoie la Vue correspondante.
Nest.js fournit le décorateur @Controller pour déclarer le contrôleur :
et le service utilisera le décorateur @Injectable pour déclarer :
Classe déclarée via @Controller, décorateur @Injectable Il sera analysé par Nest.js, les objets correspondants seront créés et ajoutés à un conteneur. Tous ces objets seront automatiquement injectés selon les dépendances déclarées dans le constructeur, qui est DI (dependency inject Cette idée s'appelle IOC (Inverse Of Control) ). .
L'avantage de l'architecture IOC est qu'il n'est pas nécessaire de créer manuellement des objets et de les transmettre aux constructeurs de différents objets en fonction des dépendances. Tout est automatiquement analysé, créé et injecté.
De plus, Nest.js offre également la capacité d'AOP (Aspect Oriented Programming), qui est la capacité de programmation orientée aspect :
Que signifie AOP ? Qu’est-ce que la programmation orientée aspect ?
Une requête peut passer par la logique du contrôleur, du service et du référentiel (accès à la base de données) :
Si vous souhaitez ajouter une logique commune à ce lien d'appel, comment devez-vous l'ajouter ? Tels que la journalisation, le contrôle des autorisations, la gestion des exceptions, etc.
La chose la plus simple à laquelle penser est de transformer directement le code de la couche Contrôleur et d'ajouter cette logique. Cela fonctionne, mais ce n'est pas élégant car ces logiques communes envahissent la logique métier. Pouvons-nous ajouter de manière transparente des journaux, des autorisations, etc. à ces logiques métier ?
Est-il possible d'ajouter une étape pour exécuter une logique commune avant et après l'appel du contrôleur ?
Par exemple :
Un tel point d'expansion horizontal est appelé un aspect, et cette méthode de programmation transparente qui ajoute une logique d'aspect est appelée AOP (programmation orientée aspect).
L'avantage d'AOP est qu'il peut séparer une partie de la logique générale en aspects pour garder la logique métier pure, de sorte que la logique d'aspect puisse être réutilisée et ajoutée et supprimée dynamiquement
En fait, le modèle oignon du middleware d'Express est également la même implémentation AOP, car vous pouvez envelopper de manière transparente une couche à l'extérieur et ajouter de la logique, et la couche interne n'en sera pas consciente.
Et Nest.js a plus de moyens d'implémenter AOP, il y en a cinq au total, dont Middleware, Guard, Pipe, Inteceptor, ExceptionFilter :,
Nest.js est basé sur Express. Naturellement, le middleware peut également être. utilisé, mais il est en outre subdivisé en middleware global et middleware de routage :
Le middleware global est le middleware d'Express. Une certaine logique de traitement est ajoutée avant et après la requête, et chaque requête sera placée ici :
Le middleware de routage est. pour un certain itinéraire, avec une portée plus petite :
Cela hérite directement du concept d'Express et est plus facile à comprendre.
Jetons un coup d'œil à certains concepts étendus de Nest.js, tels que Guard :
Guard signifie garde de routage. Il peut être utilisé pour déterminer les autorisations avant d'appeler un contrôleur et renvoyer vrai ou faux pour décider de le libérer. :
La façon de créer Guard est la suivante :
Guard doit implémenter l'interface CanActivate et la méthode canActive. Il peut obtenir les informations demandées à partir du contexte, puis effectuer une vérification des autorisations et d'autres traitements avant de renvoyer vrai ou faux.
Ajoutez-le au conteneur IOC via le décorateur @Injectable, puis activez-le dans un contrôleur :
Le contrôleur lui-même n'a pas besoin d'être modifié, mais la logique du jugement d'autorisation est ajoutée de manière transparente. Les avantages de l'architecture.
Et, tout comme le middleware prend en charge le niveau global et le niveau de routage, Guard peut également être activé globalement :
Guard peut faire abstraction de la logique de contrôle d'accès du routage, mais ne peut pas modifier les requêtes et les réponses. Intercepteur :
Interceptor signifie intercepteur. Vous pouvez ajouter un peu de logique avant et après la méthode du contrôleur cible :
La façon de créer un Inteceptor est la suivante :
Interceptor Pour implémenter l'interface NestInterceptor. , implémentez la méthode d'interception, l'appel de next.handle() appellera le contrôleur cible et vous pourrez ajouter une logique de traitement avant et après.
Contrôleur La logique de traitement avant et après peut être asynchrone. Nest.js les organise via rxjs, vous pouvez donc utiliser différents opérateurs de rxjs.
Interceptor prend en charge l'activation de chaque route individuellement, qui n'agit que sur un certain contrôleur. Il prend également en charge l'activation globale, qui agit sur tous les contrôleurs :
En plus du contrôle des autorisations de la route et du traitement. avant et après le contrôleur cible, ce sont tous des En plus de la logique générale, le traitement des paramètres est également une logique générale, donc Nest.js extrait également les aspects correspondants, c'est-à-dire Pipe :
Pipe signifie pipeline, qui est utilisé pour effectuer une vérification et une conversion des paramètres. :
La façon de créer un Pipe est la suivante :
Pipe doit implémenter l'interface PipeTransform et implémenter la méthode de transformation, qui peut exécuter des paramètres. vérification de la valeur du paramètre entrant, par exemple si le format et le type sont corrects. Lève une exception s'ils sont corrects. Vous pouvez également effectuer une conversion et renvoyer la valeur convertie.
Il y a 8 Pipes intégrées, et leurs significations peuvent être vues à partir des noms :
ValidationPipe
ValidationPipe
ParseIntPipe
ParseBoolPipe
ParseArrayPipe
ParseUUIDPipe
DefaultValuePipe
ParseEnumPipe
ParseFloatPipe
ParseIntPipe
ParseBoolPipe
ParseArrayPipe
ParseUUIDPipe
DefaultValuePipe
ParseEnumPipe
ParseFloatPipe
>
Peu importe que ce soit Pipe, Guard, Interceptor ou le contrôleur qui est finalement appelé, le processus peut être lancé Comment répondre à certaines exceptions ?
Ce mappage des exceptions aux réponses est également une logique courante. Nest.js fournit ExceptionFilter pour prendre en charge : ExceptionFilterExceptionFilter peut gérer les exceptions levées et renvoyer les réponses correspondantes : 🎜🎜🎜🎜🎜Create La forme d'ExceptionFilter est la suivante. : 🎜🎜🎜🎜🎜Tout d'abord, vous devez implémenter l'interface ExceptionFilter et la méthode catch pour intercepter les exceptions. Cependant, les exceptions que vous souhaitez intercepter doivent être déclarées avec le décorateur @Catch. Après avoir intercepté l'exception, vous pouvez. exception La réponse correspondante donne à l'utilisateur une invite plus conviviale. 🎜🎜Bien sûr, toutes les exceptions ne seront pas gérées. Seules les exceptions qui héritent de HttpException seront gérées par ExceptionFilter Nest.js possède de nombreuses sous-classes intégrées de HttpException : 🎜.BadRequestException
BadRequestException
UnauthorizedException
NotFoundException
ForbiddenException
NotAcceptableException
RequestTimeoutException
ConflictException
GoneException
PayloadTooLargeException
UnsupportedMediaTypeException
UnprocessableException
InternalServerErrorException
NotImplementedException
BadGatewayException
ServiceUnavailableException
GatewayTimeoutException
UnauthorizedException
NotFoundException
ForbiddenException
NotAcceptableException
RequestTimeoutException
ConflictException
GoneException
PayloadTooLargeException
UnsupportedMediaTypeException
UnprocessableException
InternalServerErrorException
NotImplementedException
BadGatewayException
ServiceUnavailableException
GatewayTimeoutException
Bien sûr, vous pouvez également l'étendre vous-même :
Nest.js réalise ainsi la relation correspondante entre les exceptions et les réponses, à condition que différentes HttpExceptions soient jeté dans le code , la réponse correspondante sera renvoyée, ce qui est très pratique.De même, ExceptionFilter peut également choisir de prendre effet globalement ou selon un certain itinéraire :
Un certain itinéraire :Global :
Nous comprenons le mécanisme AOP fourni par Nest.js, mais leur quoi est la relation de séquence ?
La séquence de plusieurs mécanismes AOPMiddleware, Guard, Pipe, Interceptor et ExceptionFilter peuvent tous ajouter de manière transparente une certaine logique de traitement à une certaine route ou à toutes les routes. C'est l'avantage de l'AOP.Mais quelle est la relation séquentielle entre eux ?
La relation d'appel dépend du code source.
Le code source correspondant est comme ceci :
Évidemment, lors de l'entrée sur cet itinéraire, le garde sera appelé en premier pour déterminer s'il y a une autorisation, etc. S'il n'y a pas d'autorisation, une exception sera levée ici :
Throw L'HttpException sera gérée par ExceptionFilter.
Si vous avez l'autorisation, l'intercepteur sera appelé. L'intercepteur organise une chaîne, appelle un par un, et enfin appelle la méthode contrôleur :
Avant d'appeler la méthode contrôleur, le tube sera utilisé pour traiter le paramètres. : 🎜🎜 Il est facile de penser au timing d'appel d'ExceptionFilter, qui consiste à gérer l'exception avant de répondre. 🎜🎜Et Middleware est un concept express, Nest.js en hérite simplement et il est appelé au niveau de la couche la plus externe. 🎜🎜C'est la séquence d'appel de ces mécanismes AOP. Une fois que vous aurez réglé ces problèmes, vous aurez une bonne compréhension de Nest.js. 🎜🎜Résumé🎜🎜Nest.js est encapsulé sur la base de la plate-forme http comme Express et applique des idées architecturales telles que MVC, IOC et AOP. 🎜🎜MVC est la division du contrôleur de modèle et de vue. La requête passe d'abord par le contrôleur, puis appelle le service et le référentiel de la couche modèle pour compléter la logique métier, et renvoie enfin la vue correspondante. 🎜🎜IOC signifie que Nest.js analysera automatiquement les classes avec les décorateurs @Controller et @Injectable, créera leurs objets et injectera automatiquement les objets dont il dépend en fonction des dépendances, éliminant ainsi les problèmes de création et d'assemblage manuels d'objets. 🎜🎜AOP extrait la logique générale et l'ajoute à un certain endroit via des aspects. Il peut réutiliser et ajouter et supprimer dynamiquement une logique d'aspect. 🎜🎜Middleware, Guard, Interceptor, Pipe et ExceptionFileter de Nest.js sont tous des implémentations d'idées AOP. Ce ne sont que des aspects à différents endroits. Ils peuvent tous être appliqués de manière flexible à un certain itinéraire ou à tous les itinéraires. AOP. 🎜🎜Nous avons examiné leur séquence d'appel à travers le code source. Le middleware est le concept d'Express, après avoir atteint une certaine route, Guard sera appelé en premier pour déterminer si la route a l'autorisation d'accéder, puis Interceptor sera appelé. Développez une certaine logique avant et après le contrôleur, et appelez Pipe pour vérifier et convertir les paramètres avant d'atteindre le contrôleur cible. Toutes les exceptions HttpException seront gérées par ExceptionFilter et renverront des réponses différentes. 🎜🎜Nest.js utilise cette architecture AOP pour obtenir une architecture faiblement couplée, facile à maintenir et à étendre. 🎜🎜Avez-vous ressenti les bénéfices de l'architecture AOP ? 🎜🎜Pour plus de connaissances sur les nœuds, veuillez visiter : 🎜tutoriel Nodejs🎜 ! 🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!