Cómo comenzar rápidamente con VUE3.0: ingrese y aprenda
Nest.js es un marco de back-end de Nodejs. Encapsula express y otras plataformas http para resolver problemas arquitectónicos. Proporciona MVC, IOC, AOP y otras características arquitectónicas que Express no tiene, lo que hace que el código sea más fácil de mantener y expandir.
¿Qué significan aquí MVC, IOC y AOP? Veámoslos por separado:
MVC es la abreviatura de Model View Controller. Bajo la arquitectura MVC, la solicitud se enviará primero al Controlador, quien enviará el Servicio de la capa Modelo para completar la lógica empresarial y luego devolverá la Vista correspondiente.
Nest.js proporciona el decorador @Controller para declarar el Controlador:
El Servicio será declarado con el decorador @Injectable:
Nest.js escaneará las clases declaradas a través de los decoradores @Controller y @Injectable, los objetos correspondientes se crearán y se agregarán a un contenedor. Todos estos objetos se inyectarán automáticamente de acuerdo con las dependencias declaradas en el constructor, es decir, DI (dependencia). inyectar), esta idea se llama IOC (Inverse Of Control).
La ventaja de la arquitectura IOC es que no es necesario crear objetos manualmente y pasarlos a los constructores de diferentes objetos en función de las dependencias. Todo se escanea, crea e inyecta automáticamente.
Además, Nest.js también proporciona la capacidad de AOP (Programación orientada a aspectos), que es la capacidad de programación orientada a aspectos:
¿Qué significa AOP? ¿Qué es la programación orientada a aspectos?
Una solicitud puede pasar por la lógica de Controlador, Servicio y Repositorio (acceso a la base de datos):
Si desea agregar alguna lógica general a este enlace de llamada, ¿cómo debería agregarla? Como registro, control de permisos, manejo de excepciones, etc.
Lo que es fácil de pensar es transformar directamente el código de la capa del Controlador y agregar esta lógica. Esto funciona, pero no es elegante porque estas lógicas comunes invaden la lógica empresarial. ¿Podemos agregar registros, permisos, etc. de forma transparente a estas lógicas comerciales?
¿Es posible agregar una etapa para ejecutar lógica común antes y después de llamar al Controlador?
Por ejemplo:
Estos puntos de expansión horizontal se denominan aspectos, y este método de programación que agrega de forma transparente algo de lógica de aspecto se denomina AOP (programación orientada a aspectos).
La ventaja de AOP es que puede separar cierta lógica general en aspectos y mantener la lógica empresarial pura. De esta manera, la lógica de aspectos se puede reutilizar y agregar y eliminar dinámicamente.
De hecho, el modelo cebolla del middleware de Express también es una implementación. de AOP, porque puede envolver una capa en el exterior de forma transparente y agregar algo de lógica, y la capa interna no será perceptible.
Nest.js tiene más formas de implementar AOP, hay cinco en total, incluidos Middleware, Guard, Pipe, Inteceptor, ExceptionFilter:
Nest.js se basa en Express y, naturalmente, puede usar middleware, pero se ha subdividido aún más. , Dividido en middleware global y middleware de enrutamiento:
el middleware global es el middleware de Express. Se agrega cierta lógica de procesamiento antes y después de cada solicitud.
El middleware de enrutamiento es para una ruta determinada, con un alcance menor:
Este concepto hereda directamente Express y es más fácil de entender.
Echemos un vistazo a algunos conceptos extendidos de Nest.js, como Guard:
Guard significa guardia de enrutamiento. Puede usarse para determinar los permisos antes de llamar a un controlador y devolver verdadero o falso para decidir si se libera:
La forma de crear una Guardia es la siguiente:
Guard necesita implementar la interfaz CanActivate y el método canActive. Puede obtener la información solicitada del contexto y luego realizar alguna verificación de permisos y otros procesos antes de devolver verdadero o falso.
Agréguelo al contenedor IOC a través del decorador @Injectable y luego habilítelo en un Controlador:
No es necesario modificar el controlador en sí, pero la lógica de juicio de permisos se agrega de forma transparente. Este es el beneficio de la arquitectura AOP.
Y, así como Middleware admite niveles globales y de ruta, Guard también se puede habilitar globalmente:
Guard puede abstraer la lógica de control de acceso del enrutamiento, pero no puede modificar solicitudes y respuestas. Esta lógica puede usar Interceptor:
significa interceptor. Puede agregar algo de lógica antes y después del método del controlador de destino:
La forma de crear un Interceptor es la siguiente:
Interceptor necesita implementar la interfaz NestInterceptor y llamar al método de intercepción next.handle() llamará al controlador de destino. Puede agregar algo de lógica de procesamiento antes y después.
La lógica de procesamiento antes y después del Controlador puede ser asíncrona. Nest.js los organiza a través de rxjs, por lo que puedes utilizar varios operadores de rxjs.
Interceptor admite que cada ruta se habilite individualmente, lo que solo afecta a un determinado controlador, y también admite la habilitación global, que afecta a todos los controladores:
Además del control de permisos de ruta y el procesamiento antes y después del Controlador de destino, todos son lógica común, el procesamiento de parámetros también es una lógica común, por lo que Nest.js también extrae los aspectos correspondientes, es decir, Pipe:
Tubería significa tubería, utilizada para realizar alguna verificación y conversión de parámetros:
La forma de crear una Tubería es la siguiente:
Pipe necesita implementar la interfaz PipeTransform y el método de transformación, que puede realizar la verificación de parámetros en el valor del parámetro entrante, como si el formato y el tipo son correctos. Si no es correcto, se generará una excepción. También puede realizar la conversión y devolver el valor convertido.
Hay 8 Pipes integrados, y sus significados se pueden ver en los nombres:
ValidationPipe
ParseIntPipe
ParseBoolPipe
ParseArrayPipe
ParseUUIDPipe
DefaultValuePipe
ParseEnumPipe
ParseFloatPipe
De manera similar, Pipe solo puede tener efecto en una ruta determinada, o puede tener efecto en cada ruta:
Ya sea que finalmente se llame a Pipe, Guard, Interceptor o Controller, se pueden generar algunas excepciones durante el proceso. ¿Cómo responder a ciertas excepciones?
Este mapeo de excepciones a respuestas también es una lógica común. Nest.js proporciona soporte para ExceptionFilter:
ExceptionFilter puede manejar excepciones lanzadas y devolver las respuestas correspondientes:
La forma de crear ExceptionFilter es la siguiente:
Primero, debe implementar la interfaz ExceptionFilter y el método catch para interceptar excepciones. Sin embargo, las excepciones que desea interceptar deben declararse con el decorador @Catch. Después de interceptar la excepción, puede responder con la excepción correspondiente. usuario un mensaje más amigable.
Por supuesto, no todas las excepciones serán manejadas por ExceptionFilter. Nest.js tiene muchas subclases integradas de HttpException:
BadRequestException
UnauthorizedException
NotFoundException
ForbiddenException
NotAcceptableException
RequestTimeoutException
ConflictException
GoneException
PayloadTooLargeException
UnsupportedMediaTypeException
UnprocessableException
InternalServerErrorException
NotImplementedException
BadGatewayException
ServiceUnavailableException
GatewayTimeoutException
Por supuesto, también puedes ampliarlo tú mismo:
Nest.js se da cuenta de la correspondencia entre excepciones y respuestas de esta manera, siempre que se generen diferentes HttpExceptions en el código, se devolverán las respuestas correspondientes, lo cual es muy conveniente.
De manera similar, ExceptionFilter también puede optar por surtir efecto globalmente o surtir efecto en una ruta determinada:
una ruta determinada:
Global:
Entendemos el mecanismo AOP proporcionado por Nest.js, pero ¿cuál es su relación de orden?
Middleware, Guard, Pipe, Interceptor y ExceptionFilter, puede agregar de forma transparente cierta lógica de procesamiento a una determinada ruta o a todas las rutas. Este es el beneficio de AOP.
Pero ¿cuál es la relación secuencial entre ellos?
La relación de llamada depende del código fuente.
El código fuente correspondiente es el siguiente:
Obviamente, al ingresar a esta ruta, primero se llamará a Guard para determinar si hay permiso, etc. Si no hay permiso, se generará una excepción aquí:
La HttpException lanzada será manejada por ExceptionFilter.
Si tiene permiso, se llamará al interceptor. El interceptor organiza una cadena, llama uno por uno y finalmente llama al método del controlador:
Antes de llamar al método del controlador, se utilizará pipe para procesar los parámetros:
Cada parámetro se convertirá:
Es fácil pensar en el momento de llamada de ExceptionFilter, que consiste en manejar la excepción antes de responder.
El middleware es un concepto en express, Nest.js simplemente lo hereda y se llama en la capa más externa.
Esta es la secuencia de llamada de estos mecanismos AOP. Una vez que haya resuelto estas cosas, comprenderá bien Nest.js.
Nest.js está encapsulado según la plataforma http express y aplica ideas arquitectónicas como MVC, IOC y AOP.
MVC es la división de Modelo y Controlador de Vista. La solicitud primero pasa por el Controlador, luego llama al Servicio y Repositorio de la capa Modelo para completar la lógica empresarial y finalmente devuelve la Vista correspondiente.
IOC significa que Nest.js escaneará automáticamente clases con decoradores @Controller y @Injectable, creará sus objetos e inyectará automáticamente los objetos de los que depende en función de las dependencias, eliminando la molestia de crear y ensamblar objetos manualmente.
AOP extrae la lógica general y la agrega a un lugar determinado a través de aspectos. Puede reutilizar y agregar y eliminar dinámicamente la lógica de aspectos.
Middleware, Guard, Interceptor, Pipe y ExceptionFileter de Nest.js son implementaciones de ideas de AOP. Son solo aspectos en diferentes ubicaciones y se pueden aplicar de manera flexible a una determinada ruta o a todas las rutas.
Observamos su secuencia de llamadas a través del código fuente. El middleware es el concepto de Express. En la capa más externa, después de alcanzar una determinada ruta, se llamará a Guard primero para determinar si la ruta tiene permiso para acceder. Se llamará al Interceptor. Expandirá algo de lógica hacia adelante y hacia atrás y llamará a Pipe para verificar y convertir los parámetros antes de llegar al Controlador de destino. Todas las excepciones de HttpException serán manejadas por ExceptionFilter y devolverán respuestas diferentes.
Nest.js utiliza esta arquitectura AOP para lograr una arquitectura débilmente acoplada, fácil de mantener y expandir.
¿Ha sentido los beneficios de la arquitectura AOP?