Estoy creando una API para múltiples clientes. Los puntos finales centrales /users
son utilizados por cada cliente, pero algunos puntos finales dependen de la personalización individual. Por lo tanto, podría ser que el usuario A quiera un punto final especial /groups
y ningún otro cliente tendrá esa característica. Como nota al margen , cada cliente también usaría su propio esquema de base de datos debido a esas características adicionales.
Yo personalmente uso NestJs (Express debajo del capó). Entonces, app.module
actualmente registra todos mis módulos principales (con sus propios puntos finales, etc.)
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module'; // core module
@Module({
imports: [UsersModule]
})
export class AppModule {}
Creo que este problema no está relacionado con NestJs, entonces, ¿cómo manejarías eso en teoría?
Básicamente necesito una infraestructura que pueda proporcionar un sistema básico. Ya no hay puntos finales centrales porque cada extensión es única y /users
podrían ser posibles implementaciones múltiples . Al desarrollar una nueva característica, no se debe tocar la aplicación principal. Las extensiones deben integrarse o integrarse al inicio. El sistema central se envía sin puntos finales, pero se extenderá desde esos archivos externos.
Algunas ideas vienen a mi mente
Primer enfoque:
Cada extensión representa un nuevo repositorio. Defina una ruta a una carpeta externa personalizada que contenga todos esos proyectos de extensión. Este directorio personalizado contendría una carpeta groups
con ungroups.module
import { Module } from '@nestjs/common';
import { GroupsController } from './groups.controller';
@Module({
controllers: [GroupsController],
})
export class GroupsModule {}
Mi API podría recorrer ese directorio e intentar importar cada archivo de módulo.
pros:
- El código personalizado se mantiene alejado del repositorio central
contras:
NestJs usa Typecript, así que primero tengo que compilar el código. ¿Cómo gestionaría la compilación de API y las compilaciones de las aplicaciones personalizadas? (Sistema plug and play)
Las extensiones personalizadas son muy sueltas porque solo contienen algunos archivos de texto mecanografiado. Debido al hecho de que no tienen acceso al directorio node_modules de la API, mi editor me mostrará errores porque no puede resolver las dependencias de paquetes externos.
Algunas extensiones pueden obtener datos de otra extensión. Quizás el servicio de grupos necesita acceder al servicio de usuarios. Las cosas pueden ponerse difíciles aquí.
Segundo enfoque: mantenga cada extensión dentro de una subcarpeta de la carpeta src de la API. Pero agregue esta subcarpeta al archivo .gitignore. Ahora puede mantener sus extensiones dentro de la API.
pros:
Su editor puede resolver las dependencias.
Antes de implementar su código, puede ejecutar el comando de compilación y tendrá una única distribución
Puede acceder a otros servicios fácilmente (
/groups
necesita encontrar un usuario por id)
contras:
- Al desarrollar, debe copiar sus archivos de repositorio dentro de esa subcarpeta. Después de cambiar algo, debe volver a copiar estos archivos y anular los archivos del repositorio con los actualizados.
Tercer enfoque:
Dentro de una carpeta personalizada externa, todas las extensiones son API independientes completas. Su API principal solo proporcionaría las cosas de autenticación y podría actuar como un proxy para redirigir las solicitudes entrantes a la API de destino.
pros:
- Se pueden desarrollar y probar nuevas extensiones fácilmente
contras:
La implementación será complicada. Tendrá una API principal y n API de extensión que comenzarán su propio proceso y escucharán un puerto.
El sistema proxy podría ser complicado. Si el cliente solicita que
/users
el proxy necesite saber qué extensión API escucha ese punto final, llama a esa API y reenvía esa respuesta al cliente.Para proteger las API de extensión (la autenticación es manejada por la API principal), el proxy necesita compartir un secreto con esas API. Por lo tanto, la API de extensión solo pasará las solicitudes entrantes si ese proxy coincidente se proporciona desde el proxy.
Cuarto enfoque:
Los microservicios pueden ayudar. Tomé una guía de aquí https://docs.nestjs.com/microservices/basics
Podría tener un microservicio para la gestión de usuarios, la gestión de grupos, etc. y consumir esos servicios creando una pequeña api / gateway / proxy que llame a esos microservicios.
pros:
Se pueden desarrollar y probar nuevas extensiones fácilmente
Preocupaciones separadas
contras:
La implementación será complicada. Tendrá una API principal yn microservicios que comenzarán su propio proceso y escucharán un puerto.
Parece que tendría que crear una nueva API de puerta de enlace para cada cliente si quisiera personalizarla. Entonces, en lugar de extender una aplicación, tendría que crear una API de resumen personalizada cada vez. Eso no resolvería el problema.
Para proteger las API de extensión (la autenticación es manejada por la API principal), el proxy necesita compartir un secreto con esas API. Por lo tanto, la API de extensión solo pasará las solicitudes entrantes si ese proxy coincidente se proporciona desde el proxy.