Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Análisis de microservicios y su
implementación en la Dirección de
Gestión de Tecnologías de la
Información de la Universidad
Técnica Nacional
Uso:
Acceso:
DGTI-XX
Versión 0.0A - mes 9999
Rectoría
Dirección de Gestión de Tecnologías de la Información
Tabla de contenidos
1. Justificación
2. Introducción
3. Alcance
4. Desarrollo
4.1. Análisis de infraestructura de microservicios existente
4.1.a Ausencia de pruebas de unidad en el microservicio:
4.1.b Ausencia de una carpeta “Common” para código reutilizable entre los microservicios:
4.1.c Ausencia de un API Gateway en la infraestructura de microservicios:
Imagen 1. Diagrama sobre la funcionalidad de un API Gateway. Recuperado de
https://blog.bytebytego.com/p/ep23-how-to-choose-the-right-database
4.1.d Falta de validadores sobre las peticiones http:
4.1.e Uso de Javascript(JS) en vez de Typescript(TS):
4.1.f Ausencia de un Health check en los microservicios:
4.1.g Ausencia de un ORM:
Imagen 2. Análisis FODA realizado sobre Prisma. Trabajo Propio
4.1.h La forma en la que descomponen una aplicación en servicios no cumple con los principales
patrones de microservicios:
Imagen 3. Descomposición por subdominio en microservicios de una tienda en línea.
Recuperado de (Richardson, Pattern: Decompose by subdomain, 2018)
4.1.i Uso incorrecto de JWT(Json web tokens):
Imagen 4. Captura de pantalla de código de los parámetros de una ruta pidiendo un JWT del
microservicio “flujo-aprobaciones-p-backend-desarrollo”
4.2. Propuesta de mejora en la infraestructura de microservicios
4.2.a Ausencia de pruebas de unidad en el microservicio:
4.2.b Ausencia de una carpeta “Common” para código reutilizable entre los microservicios:
4.2.c Ausencia de un API Gateway en la infraestructura de microservicios:
4.2.d Falta de validadores sobre las peticiones http:
4.2.e Uso de Javascript(JS) en vez de Typescript(TS):
4.2.f Ausencia de un Health check en los microservicios:
4.2.g Ausencia de un ORM:
Página 2 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
4.2.h La forma en la que descomponen una aplicación en servicios no cumple con los principales
patrones de microservicios:
4.2.i Uso incorrecto de JWT(Json web tokens):
4.3. Guía paso a paso y documentación
4.3.a Pruebas de Unidad
Objetivo
Detalle Teórico
Detalle Práctico
Detalle Gráfico
Imagen 4. Variables de entorno. Elaboración propia.
Imagen 5. Dependencias Mocha, Chai y cross-env. Elaboración propia.
Imagen 6. Comandos de ejecución unit. Elaboración propia.
Imagen 7. Fichero de pruebas de unidad. Elaboración propia.
Imagen 8. Resultados de pruebas. Elaboración propia.
Imagen 9. Resultados de pruebas. Elaboración propia.
Referencias Documentales
4.3.b Carpeta Common
Objetivo
Detalle Teórico
Detalle Práctico
Imagen 10. Esqueleto de carpetas. Recuperado de: Algunas buenas prácticas en el
desarrollo de API REST con NodeJS y NestJS | by Marcos Martinez | Medium
Detalle Gráfico
Imagen 11. Esqueleto de carpetas en prototipo. Elaboración propia.
Referencias Documentales
4.3.c API Gateway
Objetivo
Detalle Teórico
Detalle Práctico
Detalle Gráfico
Imagen 12. Index.ts en prototipo. Elaboración propia.
Imagen 13. Rutas en prototipo. Elaboración propia.
Página 3 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Página 4 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Objetivo
Detalle Teórico
Detalle Práctico
Detalle Gráfico
Imagen 25. Prisma.schema en prototipo. Elaboración propia.
Referencias Documentales
4.3.h
4.1.i Uso incorrecto de JWT(Json web tokens):
Objetivo
Detalle Teórico
Detalle Práctico
Detalle Gráfico
Imagen . Ejemplo de método get cuyo parámetro solicitado token debería ser eliminado
Imagen . Ejemplo de una petición por axios colocando en el JWT en el Authorization header
. Elaboración propia.
Imagen . Ejemplo de cómo obtener el token de los headers de una petición http con express
Referencias Documentales
5. Anexos
6. Referencias bibliográficas
Página 5 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
1. Justificación
La Dirección de Gestión de Tecnologías de la Información (de ahora en adelante DGTI) se encuentra
en un proceso de desarrollo de unos sistemas de información para la Universidad Técnica Nacional
donde recientemente se adoptó el patrón de microservicios, para este proyecto se decidió reclutar
estudiantes cursando su práctica profesional. A partir del análisis preliminar sobre la estructura
existente para el aprovechamiento de microservicios, se detectaron algunos aspectos que podrían
tomarse en cuenta para el mejoramiento de la estructura y su implementación.
De esta observación, nació la iniciativa de este proyecto por parte de la Dirección, sobre hacer un
diagnóstico sobre la infraestructura e implementación actual de los microservicios, con la finalidad de
presentar los hallazgos encontrados y recomendaciones respectivas para la posible mejora del
proceso de desarrollo.
2. Introducción
El desarrollo de este informe se divide en tres secciones; la primera corresponde con el análisis de la
infraestructura actual de los microservicios donde se detallan las observaciones encontradas, según
información extraída de algunas muestras de código y entrevistas con el equipo de desarrollo. En la
segunda sección, se enlistan las recomendaciones de mejora a raíz de las observaciones
encontradas en la primera parte. Por último, se adjuntará la documentación y guías necesarias para
llevar a cabo las recomendaciones propuestas.
3. Alcance
El alcance de este documento cubre el análisis sobre la información compartida en las
reuniones con el equipo de desarrollo e infraestructura y las copias de los microservicios
compartidos “flujo-aprobaciones-p-backend-desarrollo” y
“flujo-aprobaciones-s-backend-desarrollo”.
Respecto de la propuesta de mejoramiento, esta se limitará a las observaciones encontradas
durante el análisis y cubrirán aspectos de estructura e implementación que pueden afectar
indirectamente el flujo de operaciones actual.
Dichos cambios y su implementación no se abordarán dentro de este documento ni el
Página 6 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
4. Desarrollo
4.1.b Ausencia de una carpeta “Common” para código reutilizable entre los
microservicios:
Uno de los principios de los microservicios es el “ Common Closure Principle” que según (Richardson,
Pattern: Decompose by subdomain, 2018) hace referencia a que las clases que cambian por la
misma razón deben estar siempre en el mismo paquete, en este caso hay un claro ejemplo de clases,
cuya función se rige por proveer a los microservicios con los servicios básicos para funcionamiento,
tales como el archivo “db.js” que bajo la estructura actual se termina convirtiendo en código duplicado
al colocarse en todos los microservicios y un cambio requerido en este tipo de archivos, puede llevar
un problema de sincronización debido a la descentralización de estas clases que deberían
encontrarse en un solo paquete (Common) y ser consumido por todos los microservicios.
Página 7 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
El API Gateway en la actualidad, es una práctica estándar en el desarrollo de API’s debido a que
este patrón está diseñado para lidiar con API’s y su tráfico, con el fin de resolver problemas de
mantenibilidad, extensibilidad, seguridad, observabilidad, gestión del ciclo de vida del producto y
monetización; debido a estas características que definen el porqué de su implementación ,es la razón
de por qué es utilizado por gigantes de la industria como Netflix, Google, Amazon, Microsoft, etc… y
es altamente respaldado como estándar de las buenas prácticas en las principales literaturas
actuales sobre desarrollo de API’s.
Adicionalmente, cabe recalcar que la forma en la que está trabajando la DGTI de mantener un
Gateway para cada microservicio según (Kanjilal, 2021) es considerado uno de los anti-patrones
actuales de los microservicios.
Página 8 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Página 9 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
información necesaria para su debida utilización o a la ausencia de una validación inicial que
hubieran causado el rechazo de la petición.
Dentro de las principales funcionalidades del ORM de elección llamado Prisma que fue escogido
después de haber revisado otros en el mercado sobresale que:
● Aumenta la velocidad de desarrollo en relación con las consultas a la base de datos
● Estandariza los métodos para ser agnóstico a la base de datos
● Tiene soporte para funcionalidades en demanda como filtrado json, transacciones y consultas
NoSQL.
● Tiene soporte para las bases de datos más utilizadas y comunes
Página 10 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
● Permite el desarrollo seguro contra vulnerabilidades comunes como las inyecciones SQL.
● Contiene código abierto y de uso gratuito, también tiene una gran comunidad de
desarrolladores detrás y recibe actualizaciones frecuentes.
4.1.h La forma en la que descomponen una aplicación en servicios no cumple con los
principales patrones de microservicios:
Actualmente la literatura sobre microservicios soporta dos principales patrones como mejores
prácticas, el primer patrón es descomponer por contexto de subdominio (Richardson, Pattern:
Decompose by subdomain, 2018) que utiliza el fundamento del Domain-Driven Design (DDD) para
establecer el dominio como la aplicación y sus subdominios como sus microservicios, y el segundo
patrón, descomponer por capacidad de negocio (Richardson, Pattern: Decompose by business
capability, 2019) define que se debe descomponer por lógica de negocio, un enfoque bastante similar
al de subdominio, pero descompone por lo que vendrían siendo los módulos de la lógica de negocio
sin importar cómo estén estructurados los subdominios.
Página 11 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
basados en la experiencia de quienes escriben este documento, este patrón de descomposición por
subdominio suele ser el más usado en la industria.
Página 12 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Aunque en las peticiones HTTP se esté usando TLS (Transport Layer Security) el url puede ser
obtenido por un tercero de diferentes formas como los logs de un web server, el historial del
buscador, el referer header si la página web utiliza dependencias o recursos de terceros, también
existe la opción por medio de ingeniería social, que un usuario podría copiar un url completo y
compartirlo directamente con un atacante, tal y como se menciona en (Woda, 2021.)
Página 13 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
4.2.b Ausencia de una carpeta “Common” para código reutilizable entre los
microservicios:
El concepto del uso de un “Common” puede implementarse de múltiples maneras, pero usualmente
consiste en una carpeta de nivel raíz del microservicio donde se tienen todas las clases, interfaces y
servicios que pueden utilizarse en dos o más microservicios para evitar código repetido, problemas
de mantenimiento y sincronización en caso de ser requerido un cambio en el código compartido.
Como la DGTI tiene un enfoque multi-repositorio, la recomendación sería tratar el “Common” como
un proyecto aparte que contenga los elementos de código compartidos entre los microservicios
previamente mencionados y realizar una actualización de dicha carpeta en los microservicios
respectivos cuando el proyecto de base de ”Common” recibe una modificación. Como parte de la
propuesta se implementará un prototipo de cómo luciría un Common de los proyectos de
microservicios que maneja la DGTI con el objetivo de que lo puedan adoptar.
Página 14 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
4.2.h La forma en la que descomponen una aplicación en servicios no cumple con los
principales patrones de microservicios:
El proyecto prototipo usará otro de los proyectos realizados en paralelo por estudiantes de la práctica
profesional y utilizará el enfoque de descomposición por subdominio para agrupar el servicio y tendrá
una estructura de proyecto sugerida, de forma que facilite el trabajo por medio de este enfoque.
Objetivo
Mejorar el proceso de control de calidad del código mediante la implementación de pruebas de
unidad para validar el comportamiento y la lógica de los microservicios
Página 15 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Detalle Teórico
Las arquitecturas de microservicios cada vez toman más fuerza en el mercado debido a su
flexibilidad de desarrollo, comunicaciones independientes y mejor escalabilidad, entre otros. Por lo
cual, se han generado distintas estrategias para medir su calidad. Una de ellas es el uso de pruebas
de unidad, que, aunque ya se conocen desde las arquitecturas monolíticas, su importancia las hace
imprescindibles para medir la calidad de los métodos o secciones de código que utilizan los
microservicios.
Las pruebas de unidad por su parte, son pruebas simples que validan código en sus fases tempranas
de su desarrollo. Con ellas se busca la detección de errores que normalmente, sin las pruebas de
unidad, se detectarán hasta fases avanzadas del proyecto. Además, permiten ahorrar tiempo cuando
se necesita validar si alguna modificación en el código afectó la lógica de alguna clase o función,
entre otros.
Para este caso se utilizan dos librerías especializadas en realizar pruebas de unidad en Javascript
llamadas: Mocha y Chai. Ambas librerías trabajan en conjunto para realizar pruebas de unidad muy
sólidas para los microservicios. Además, aumentarán el nivel de calidad del código. Por otro lado,
también se utilizará una librería para la colocación de variables de entorno en los comandos de
ejecución llamado: cross-env.
Mocha es un framework utilizado para la elaboración de pruebas. Está basado en Javascript y se
ejecuta en Node.js. Entre varias de sus funcionalidades tiene: la creación de reportes síncronos y
asíncronos, ejecución de pruebas, creación de reportes, entre otros.
Chai es una librería de aserciones. Es muy compatible con los marcos de pruebas y se adapta
fácilmente a estos. Cuenta con diferentes interfaces que permite a los desarrolladores utilizar el que
mejor se adapte a su situación. Por ejemplo: assert, expect y should.
Detalle Práctico
Instalación:
Para instalar Mocha y Chai se debe ejecutar el siguiente comando en la terminal del proyecto:
npm install mocha –save
npm install chai –save
npm install --save-dev cross-env
Lo ideal es que cada microservicio contenga su propia carpeta de “tests”. Por lo cual, accedemos a
un microservicio mediante la terminal y creamos la carpeta:
mkdir tests
Dentro de cada carpeta “tests” de los microservicios deben ir los ficheros de pruebas.
Ejecución
Para la ejecución normalmente se apoya con las cualidades de npm. En el fichero package.json se
crea un parámetro para la ejecución de las pruebas. Por ejemplo:
Página 16 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Para agregar variables de entorno, en los parámetros de ejecución se debe colocar “cross-env”
seguido de todas las variables que se necesiten. En este ejemplo se muestran dos variables de
entorno:
"build": "cross-env FIRST_ENV=one SECOND_ENV=two node ./my-program"
Detalle Gráfico
Las variables de entorno en el prototipo funcionan para elegir qué base de datos se va a utilizar para
hacer las pruebas. En este caso se cuenta con “test” que sería una base de datos ficticia y es la que
por defecto, utiliza el resto del proyecto
Página 17 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Página 18 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Página 19 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Referencias Documentales
cross-env - npm (npmjs.com)
Chai (aaronsofaly.github.io)
Mocha - the fun, simple, flexible JavaScript test framework (mochajs.org)
Objetivo
Evitar la redundancia y duplicado de archivos, código, entre otros, mediante la implementación de
una carpeta común para almacenar todos aquellos archivos que sean requeridos por distintas partes
de la aplicación.
Página 20 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Detalle Teórico
Los lenguajes de programación, en su mayoría, permiten crear estructuras al gusto del desarrollador.
En ocasiones, se basan en el tipo de proyecto que se vaya a realizar para así ir montando la
estructura. Sin embargo, el crear una estructura al gusto o pensando que esa forma es la mejor,
puede resultar en muchos problemas debido a la ausencia de un estándar de infraestructura.
El si está bien o mal estructurado un proyecto es muy relativo con respecto a cada desarrollador.
Algunas estructuras suelen ser más sencillas de comprender para unas personas, mientras que para
otros no son nada funcionales. Por lo que, al final, la mejor recomendación es ir probando
metodologías hasta encontrar una con la se sienta familiarizado. Además, lo importante es no
terminar creando un proyecto inmanejable con archivos repetidos, dependencias cruzadas, entre
otros.
La carpeta “common” es una buena práctica que se implementa comúnmente en los proyectos que
utilizan librerías, componentes, entre otras cosas. La idea es colocar dentro de esta carpeta todos
aquellos elementos que son reutilizados en distintas partes de la aplicación. Aquellos archivos que
trabajen individualmente pueden ir en la raíz de la carpeta “common”, pero aquellos componentes
que requieran de varios archivos para funcionar deben ser agrupados en subcarpetas.
Detalle Práctico
Creación:
Se crea la carpeta:
mkdir common
Página 21 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Imagen 10. Esqueleto de carpetas. Recuperado de: Algunas buenas prácticas en el desarrollo de API
REST con NodeJS y NestJS | by Marcos Martinez | Medium
Detalle Gráfico
En el prototipo la carpeta “common” luce así:
Referencias Documentales
Algunas buenas prácticas en el desarrollo de API REST con NodeJS y NestJS | by Marcos Martinez |
Medium
Página 22 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Objetivo
Agilizar el procesamiento de solicitudes de los diferentes microservicios mediante la implementación
de un intermediario que actuará como único punto de entrada para realizar un mejor filtrado y
alivianar las validaciones.
Detalle Teórico
Cuando se cuenta con una infraestructura basada en microservicios, los clientes suelen hacer
llamados a más de un microservicio. En este caso, como las llamadas están siendo directas entre el
cliente y los microservicios, un solo cliente debe realizar múltiples llamadas.
Además, si la aplicación comienza a crecer y evolucionar, manejar todos estos llamados de los
clientes puede ser una tarea muy difícil. De igual manera, si en un futuro se necesitará cambiar
servicios de los que los clientes llaman y ya tienen configurados, esto podría generar un alto impacto
en ellos.
Por eso, se dice que si no se cuenta con un intermediario entre los llamados y los clientes se podrían
generar problemas como:
● Dificultades al cambiar por miedo a afectar las configuraciones de los clientes
● Presentar problemas de latencia por los múltiples llamados que requieren los clientes
● Todos los microservicios pueden ser fácilmente atacados al tener que estar expuestos
Por lo tanto, la mejor recomendación a la hora de tener una aplicación múltiples servicios que aspiran
a escalar y evolucionar, es contar con un intermediario como un API Gateway. El API Gateway
pasará a ser el único punto por donde los clientes pueden realizar sus llamadas a los microservicios.
Este cuenta con varios beneficios como:
● Los microservicios expuestos pueden ser diferentes entre cada cliente
● Tiene autenticación
● Manipulación de certificados
● Almacenamiento caché
● Direccionamiento
Detalle Práctico
Debemos entender que cuando hablamos de un API Gateway al final es un conjunto de librerías
trabajando como una sola. No existe como tal, una sola forma de hacer un API Gateway. Cada
persona decide qué librerías quiere usar para autenticar, cuales para llevar registros log, entre otros.
Por lo tanto, crear un detalle práctico es muy difícil, porque todo depende de las librerías que quiera
usar y el contexto del proyecto. Por lo cual, en las referencias documentales adjuntamos un enlace
con un tutorial de cómo crear un API Gateway con librerías similares a las utilizadas en el prototipo.
Detalle Gráfico
El index.ts del prototipo:
Página 23 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Página 24 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Página 25 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Referencias Documentales
Create an API Gateway Using NodeJS and Express | by Bram Janssen | Geek Culture | Medium
The API gateway pattern versus the direct client-to-microservice communication | Microsoft Learn
Objetivo
Validar el contenido de un llamado a un microservicio mediante la implementación de una librería que
permita verificar que todos los requisitos de las peticiones sean correctos para evitar tener que
procesar peticiones innecesarias y remover de la lógica de los microservicios condicionales
repetitivos.
Detalle Teórico
Desde el comienzo de internet, el uso de formularios online ha sido uno de los fuertes de las páginas
web. Por lo cual, los programadores han tenido que aprender desde hace muchos años como crear,
manipular y validar formularios en las aplicaciones web. Claramente, los formularios han ido
evolucionando en cuanto a diseño, son mucho más interactivos en la actualidad. Sin embargo, algo
que se mantiene igual es la validación de los datos que ingresa una persona.
Los datos que envía un usuario a la aplicación cuentan con varias fases de chequeo. Con la librería
Yup se validan los parámetros que se envían a través de un URL, ya que es un validador de
formularios por excelencia. Yup nos permitirá crear conjuntos de reglas que posteriormente validará
con la información del usuario. Estos conjuntos de reglas son mejor conocidos como: esquemas.
Claramente, existen otras librerías en el mercado que realizan exactamente el mismo trabajo que
Yup, pero esta cuenta con ciertos beneficios como:
● Es una librería altamente declarativa
● Es intuitiva
● Cuenta con una gran popularidad lo que hace que reciba mejoras con regularidad.
Detalle Práctico
Instalación:
Su instalación se puede realizar con NPM
npm i yup
Creación de esquemas:
Los esquemas son las validaciones que Yup buscará en la información recibida de los clientes:
import { object, string, number, boolean } from "yup";
const schema = object({
name: string(),
alias: string(),
age: number(),
Página 26 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
email: string(),
isChosenOne: boolean(),
});
Validación:
Con los esquemas ya realizados, se utiliza el método validate con la información a validar como
parámetro
try{
await schema.validate(user);
}catch(err){
// Los datos no han pasado la validación
}
Detalle Gráfico
Esquema en el prototipo:
Página 27 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Validador:
Página 28 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Referencias Documentales
jquense/yup: Dead simple Object schema validation (github.com)
4.3.e Typescript
Objetivo
Mejorar el desarrollo de código mediante la implementación de un lenguaje seguro que permita
validar tipos de variable, utilizar interfaces, entre otros.
Detalle Teórico
Typescript se trata de un lenguaje de programación abierto basado en Javascript. Esto quiere decir
que cuenta con todas las funcionalidades y herramientas de Javascript, pero agrega unas cuantas
mejoras. Al compilar, Typescript convierte todo su código en Javascript.
Sus principales mejoras son:
Interfaces: funcionan para asegurar que los objetos recibidos contengan una correcta
estructura y tipos de variables.
Tipos de datos: En lenguajes como Javascript a las variables no se les asigna el tipo de dato
que van a contener y aceptan cualquier dato. Con Typescript se asegura de que las variables reciban
el tipo para el que fueron hechas y en caso de no ser así, muestran un error antes de la ejecución del
programa.
De igual forma cuenta con ventajas como: ágil detectando errores, sintaxis sencilla de comprender,
utiliza gestores de paquete (NPM), compatibilidad con los dispositivos que utilizan Javascript, admite
el trabajo simultáneo entre varias personas, lectura simple y limpia, entre otros.
Detalle Práctico
Instalación:
Para instalarlo se debe ejecutar el siguiente comando en la terminal del proyecto:
npm install -g typescript
Una forma de comprobar que se ha instalado correctamente es ejecutando el comando para mostrar
que versión se encuentra instalada:
tsc -v
Uso:
Crear un archivo .ts en el proyecto y colocar un código dentro. Luego ejecutarlo utilizando el comando
tsc <Nombre del archive>.ts
Para evitar tener que compilar el archivo cada vez que lo modificamos utilizamos --watch:
tsc <Nombre del archive>.ts --watch
Página 29 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Detalle Gráfico
En el prototipo se ve así:
tsconfig.json
Página 30 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Referencias:
TypeScript: The starting point for learning TypeScript (typescriptlang.org)
Página 31 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Interfaces:
Página 32 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Referencias Documentales
TypeScript: Documentation - TypeScript for JavaScript Programmers (typescriptlang.org)
TypeScript: TSConfig Reference - Docs on every TSConfig option (typescriptlang.org)
TypeScript: The starting point for learning TypeScript (typescriptlang.org)
TypeScript: How to set up TypeScript (typescriptlang.org)
Objetivo
Monitorear el estado de los microservicios mediante la implementación de un patrón que valide el
estado actual de las solicitudes para detectar de manera temprana cualquier fallo que se presente.
Detalle Teórico
Con la evolución de las infraestructuras a microservicios, la necesidad de implementar sistemas de
monitoreo se ha vuelto indispensable. Debido a que todas las partes de la infraestructura se
encuentran separadas y se comunican por medio de la red, aumentan las posibilidades de que se
genere algún fallo. Por lo tanto, lo ideal es acompañar a los microservicios con algún monitoreo que
genere alertas, tenga acciones automatizadas y genere reportes, entre otros, que permita a los
administradores tener una respuesta rápida ante algún evento.
Existen muchas razones por las que estar continuamente revisando el estado de los microservicios
se vuelve importante. Ya sea porque así lo piden las políticas de la empresa o porque se cuenta con
configuraciones difíciles. La más importante es porque hay que saber que por el hecho de que un
código no cambie a lo largo del tiempo, no significa que su comportamiento va a ser el mismo.
A la hora de utilizar microservicios se debe tomar en cuenta que se depende de componentes
hardware, librerías de terceros, dependencias con otros equipos, entre otros. Lo que tienen en común
todos estos es que ninguno asegura una disponibilidad del 100%. De hecho, se dice que
probablemente al corto tiempo de haber implementado un servicio en producción, este va a fallar,
siempre fallan. Entonces, lo importante es que los desarrolladores lo sepan antes que el cliente.
Detalle Práctico
Los “health checks” pueden ser tan elaborados como uno desee. No necesariamente se necesita una
librería, lo importante acá es realizar las funciones correctas que revisen el estado de los
microservicios. Por ejemplo, utilizando la librería healthchecks-apis para revisar las conexiones a las
bases de datos se vería algo así:
Página 33 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Página 34 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Imagen 22. healthchecks-apis. Recuperado de: Health Checks in Node.js. One of the most important
patterns in… | by Ahmad Mhaish | JavaScript in Plain English
Es importante mencionar que las funciones “health check” siempre deben llevar el “await” en su
código, ya que sin esto el servidor no va a esperar que terminen de hacer sus validaciones y se va a
iniciar de todos modos.
Detalle Gráfico
En el prototipo no se utilizó una librería y quedó estructurada de la siguiente manera. Dentro de la
carpeta “common” habrá un fichero llamado “utils” que contendrá todas aquellas funciones útiles que
usan todos los microservicios. En este archivo es dónde se crea la función “health check”.
Básicamente, esta función va a recibir todos los servicios que tenga la aplicación. Por ejemplo:
consumo de APIs, servicios terceros, entre otros.
Todos los proveedores deberían tener el método “checkConnection” la cual es necesaria para el
“health check”.
Página 35 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Si los “check connection” fallan, se retorna un “false” al “health check” y este es que le imprime un
mensaje de error al usuario.
En la siguiente imagen se puede observar un llama al API healtcheck donde indica que
microservicios están corriendo y prueba la conexión con la BD
Página 36 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Referencias Documentales
Health Check (microservices.io)
Objetivo
Simplificar el desarrollo de consultas a la base de datos mediante la implementación de un modelo de
programación que permita enlazar a las bases de datos relacionales con una estructura lógica de
entidades.
Detalle Teórico
Cuando se entrelaza la estructura de las bases de datos con una estructura lógica de entidades, se
facilita el proceso de creación de bases de datos para los desarrolladores. Debido a que utilizar una
Página 37 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
estructura lógica hace más sencilla su comprensión, análisis y programación. Los programadores
reconocen fácilmente como crear, modificar o eliminar bases de datos utilizando entidades. Ya que es
un modelo con el que están mucho más familiarizados.
Los ORMs son los encargados de hacer esta transición entre ambas estructuras. Una vez que el
ORM se instala y entrelaza toda la información, las acciones CRUD se realizan por medio de él. El
ORM libera al desarrollador de esa necesidad de comprender y analizar código SQL. Ya que, este
mismo cuenta con métodos que sustituyen a las consultas que se hacen en las bases de datos. Por
lo tanto, pasaremos de crear líneas de código SQL para crear, consultar, modificar o eliminar una
base de datos, a crear instancias, llamar métodos, enviar parámetros, entre otros.
Detalle Práctico
Instalación:
Se puede instalar con NPM
npm install prisma --save-dev
Ejecución:
Para iniciar prisma se corre el comando:
npx prisma init
Esto creará un archivo .env donde debemos colocar nuestro string de conexión a la base de datos:
#.env
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail:
https://pris.ly/d/prisma-schema#using-environment-variables
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQL Server and
SQLite.
# See the documentation for all the connection string options:
https://pris.ly/d/connection-strings
DATABASE_URL="example://example:mysecretpassword@localhost:5432/postgres?schema=quotes"
El archivo prisma.schema es la representación de la base de datos SQL en ORM, por lo tanto ahí es
donde podemos cambiar, crear o modificar nuestras bases de datos.
Si se desea la aplicación de los cambios para la base de datos se corre el siguiente comando:
npx prisma migrate dev --name init
Detalle Gráfico
El prisma.schema del prototipo:
Página 38 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Referencias Documentales
Prisma Client - Auto-generated query builder for your data
Concepts (prisma.io)
What is Prisma? (Overview)
Objetivo
Aplicar las mejores prácticas de microservicios mediante la implementación de un patrón de
descomposición basado en subdominios para facilitar la separación de responsabilidades en cada
uno de los microservicios
Detalle Teórico
A la hora de implementar microservicios en empresas que ya cuentan con sistemas hechos, y que en
su mayoría son monolíticos, se pueden utilizar diferentes estrategias para realizar esta transición.
Dicha transición es mejor conocida como “descomposición del servicio”. Una de las técnicas más
populares es la descomposición por subdominios.
La descomposición por subdominios funciona para dividir el sistema actual de una empresa en
componentes con responsabilidades y dependencias claramente definidas. Además, se establecen
Página 39 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
las relaciones que van a tener los microservicios unos con otros y sus respectivos límites. Estos
subdominios se pueden conocer como:
● Núcleo: es un diferenciador clave del sistema
● Apoyo: está relacionado con el sistema, pero no con los diferenciadores
● Genérico: no es específico para el sistema, pero se puede utilizar
Al modular e implementar una arquitectura de microservicios con el patrón de subdominio, se pueden
adquirir las siguientes características:
● Se libera el acoplamiento
● Gran escalabilidad
● Sistemas predecibles
● Independencia de protocolos y tiempos
Detalle Práctico
Para lograr dividir un sistema en subdominios, se debe analizar todas las operaciones que requiere
para lograr el objetivo del negocio. Para facilitar este análisis podemos dividir las operaciones en
pasos para posteriormente analizar que se requiere en cuanto a microservicios. Por ejemplo, analice
las operaciones de un restaurante virtual que realiza las entregas mediante sistema express.
Pasos:
● Paso 1: El usuario llega al sitio web y visualiza todos los productos disponibles. Puede realizar
un filtrado de los productos. También puede ordenar los productos mediante diferentes reglas.
● Paso 2: El usuario elige que desea comprar y lo añade al carrito.
● Paso 3: El usuario confirma el pedido, procede a pagar y el pedido llega a la cocina.
● Paso 4: La cocina recibe el pedido y comienza con su preparación.
● Paso 5: El usuario puede monitorear el estado de su pedido en la cocina.
● Paso 6: Una vez la cocina tiene el pedido listo, confirma su estado y lo pasa al sistema
express.
● Paso 7: El usuario puede monitorear el estado de su pedido en el sistema express hasta que
lo recibe.
Análisis de los pasos:
● Paso 1: Este paso requiere un subdominio encargado de administrar los productos y que los
muestre mediante una interfaz. Acá se genera el subdominio de productos.
● Paso 2: Este paso requiere un subdominio encargado de administrar los pedidos de los
clientes y guardar la información necesaria de lo que el cliente ha añadido. Acá se genera el
subdominio de pedidos.
● Paso 3: Este paso requiere un subdominio encargado de administrar los pagos de los clientes,
capaz de mostrar una interfaz donde el cliente pueda seleccionar métodos de pago, ingresar
datos, validación de tarjetas, entre otros. Acá se genera el subdominio de pagos.
● Paso 4: Este paso requiere un subdominio encargado de administrar los pedidos en la cocina.
Debe ser capaz de interactuar con la cocina, medir el progreso de un pedido, medir tiempos,
entre otras cosas. Acá se genera el subdominio de cocina.
● Paso 5: Este paso es abarcado por el subdominio de pedidos que interactúa con el de cocina
para actualizar el estado de los pedidos.
Página 40 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Detalle Gráfico
En el prototipo se utilizo la descomposición por subdominios, separando a los procesos principales y
asignándoles sus propios microservicios.
Referencias Documentales
Descomposición por subdominio - AWSOrientación prescriptiva (amazon.com)
Objetivo
Remover el uso inseguro de JWT en las peticiones http y mostrar una recomendación que aborde
una alternativa segura.
Página 41 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Detalle Teórico
Cuando realizamos peticiones por medio de https (versión segura de http) todo el paquete incluyendo
el url está en encriptado en transporte, pero es posible que sus contenidos específicamente el url sea
logueado por un servidor, almacenado en el dispositivo, compartido a terceros o directamente
compartido por el usuario.
Por otro lado, tenemos el JWT que es un objeto tipo json y su función es propagar información de
forma segura y efectiva que a la vez es verificada dado que lleva una firma que se produce del lado
del servidor para nunca tener que confiar a ciegas en los datos del lado del cliente, debido a sus
características este usualmente se utiliza para verificar la identidad de un usuario y por esa razón se
toma las medidas como su caducidad por tiempo de expiración o anulación por otro inicio de sesión.
El escenario que sucede actualmente es que el JWT está siendo usado para verificar la identidad de
los usuarios, pero está siendo usado de manera que se solicita en los parámetros de los url y por
consiguiente dado la explicación anterior se incrementa la posibilidad de que caiga en las manos de
un tercero incluso bajo el uso de TLS.
Detalle Práctico
Es necesario empezar por remover la solicitud del token (JWT) de todas las rutas del servidor
express de los microservicios para que estas rutas que reciben las peticiones http puedan funcionar
sin el token siendo enviado en el url.
Después la alternativa segura es trasladar el envío del token preferiblemente por estándar a los
headers en un campo llamado “authorization” o de ser necesario podría ser incluso trasladado a el
body de las peticiones.
Detalle Gráfico
Imagen 27. Ejemplo de método get cuyo parámetro solicitado token debería ser eliminado
Página 42 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Imagen 28. Ejemplo de una petición por axios colocando en el JWT en el Authorization header .
Elaboración propia.
Imagen 29. Ejemplo de cómo obtener el token de los headers de una petición http con express
Referencias Documentales
https://blog.httpwatch.com/2009/02/20/how-secure-are-query-strings-over-https/
https://community.auth0.com/t/can-i-securely-pass-a-jwt-in-the-url-query-parameters-of-a-get-r
equest/65678
6. Referencias bibliográficas
Codemotion. (2022). Codemotion. Obtenido de Why You Should Use Typescript for Your Next Project:
https://www.codemotion.com/magazine/backend/why-you-should-use-typescript-for-your-next-
project/#:~:text=In%20terms%20of%20software%20development,can%20create%20errors%2
0during%20production.
HttpWatch. (2009). HttpWatch. Obtenido de How Secure Are Query Strings Over HTTPS?:
https://blog.httpwatch.com/2009/02/20/how-secure-are-query-strings-over-https/
Página 43 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Página 44 de 45
Rectoría
Dirección de Gestión de Tecnologías de la Información
Márquez, R. (2017, 02 15). Testeando JavaScript con Mocha y Chai. Retrieved from paradigma
digital:
https://www.paradigmadigital.com/dev/testeando-javascript-mocha-chai/#:~:text=Mocha%20y
%20Chai%20nos%20permiten,la%20conocida%20pir%C3%A1mide%20de%20Cohn.
Mendes, F. (2021, 06 22). Schema Validation with Yup and Express.js. Retrieved from dev:
https://dev.to/franciscomendes10866/schema-validation-with-yup-and-express-js-3l19
Mhaish, A. (2020, 09 27). Health Checks in Node.js. Retrieved from plainenglish:
https://javascript.plainenglish.io/health-checks-in-nodejs-37fb2b1cdc65
Muro, J. A. (2018, 06 28). ¿Qué es un ORM? Retrieved from deloitte:
https://www2.deloitte.com/es/es/pages/technology/articles/que-es-orm.html
risingstack. (2022, 05 31). Building an API Gateway using Node.js. Retrieved from risingstack:
https://blog.risingstack.com/building-an-api-gateway-using-nodejs/
Serrano, J. (2018, 07 01). Test con mocha y chai. Retrieved from johnserrano.co:
https://johnserrano.co/blog/test-con-mocha-y-chai
tkssharma. (2022, 03 21). Prisma ORM with Node JS. Retrieved from medium:
https://medium.com/tkssharma/prisma-orm-with-node-js-17c0b72faf32
Woda, D. (2021). auth0. Obtenido de Can I securely pass a JWT in the URL query parameters of a
GET request?:
https://community.auth0.com/t/can-i-securely-pass-a-jwt-in-the-url-query-parameters-of-a-get-r
equest/65678
Wosinek, M. (2021, 12 22). ¿Cuál es el objetivo de las pruebas unitarias? Retrieved from conoce.dev:
https://conoce.dev/cual-es-el-objetivo-de-las-pruebas-unitarias
krypton solid. (02 de 01 de 2022). Desglose las plataformas mediante una estrategia de
descomposición de servicios. Obtenido de krypton solid:
https://kryptonsolid.com/desglose-las-plataformas-mediante-una-estrategia-de-descomposicion-de-se
rvicios/
Página 45 de 45