<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Francisco Javier Guerrero Martinez</title>
    <description>The latest articles on DEV Community by Francisco Javier Guerrero Martinez (@diwolf).</description>
    <link>https://dev.to/diwolf</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F702748%2F52af8ff9-603a-4c15-b0b2-c89aae6d51eb.jpeg</url>
      <title>DEV Community: Francisco Javier Guerrero Martinez</title>
      <link>https://dev.to/diwolf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/diwolf"/>
    <language>en</language>
    <item>
      <title>Desplegando un Backend Graphql NodeJS Azure Container Apps</title>
      <dc:creator>Francisco Javier Guerrero Martinez</dc:creator>
      <pubDate>Sun, 09 Oct 2022 21:42:07 +0000</pubDate>
      <link>https://dev.to/diwolf/desplegando-un-backend-graphql-nodejs-azure-container-apps-235j</link>
      <guid>https://dev.to/diwolf/desplegando-un-backend-graphql-nodejs-azure-container-apps-235j</guid>
      <description>&lt;p&gt;En esta entrada realizaremos el despliegue de un backend utilizando Azure DevOPS (pipelines), Azure Registries y Azure Containers Apps&lt;/p&gt;

&lt;h1&gt;
  
  
  Requisitos
&lt;/h1&gt;

&lt;p&gt;Cuenta en Azure &lt;br&gt;
Servicio Azure Registries Activo&lt;br&gt;
Servicio Azure Containers Apps Activo &lt;br&gt;
Cuenta en Azure DevOps &lt;/p&gt;

&lt;h1&gt;
  
  
  Creando servicio Registries
&lt;/h1&gt;

&lt;p&gt;Partiré de la premisa que ya cuentas con una cuenta en Azure, navegamos en el buscador de servicios y buscamos el Servicio Azure Container Registries&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vBjuddH3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77ab1i2kuv8bo4o4s5w0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vBjuddH3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77ab1i2kuv8bo4o4s5w0.png" alt="Image description" width="118" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez dentro, deberás de llenar los campos marcados como obligatorios&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NQmxFCy2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nn4omhj9tuzrlk6ha7fb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NQmxFCy2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nn4omhj9tuzrlk6ha7fb.png" alt="Image description" width="811" height="876"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para esta entrada te recomendaré que utilices en SKU: Basic, esto para reducir el gasto en la factura y si tu APP no tiene bastante demanda. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4ckKnzsn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5js6gtp76js7l53n7blw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4ckKnzsn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5js6gtp76js7l53n7blw.png" alt="Image description" width="755" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Al ser un registro básico, este estará público aplicará el mismo caso para el tipo de Encryptation. Si deseas agregar los tags puedes hacerlo para este ejemplo dejaré todo en blanco y saltaré hasta la última pantalla &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1ENtcJKq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4p8g1f12k1m1sogm4s0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1ENtcJKq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4p8g1f12k1m1sogm4s0.png" alt="Image description" width="601" height="719"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Damos clic en el botón create para crear el recurso. &lt;/p&gt;

&lt;h1&gt;
  
  
  Conectado Azure DevOPS Pipelines con Azure Registries
&lt;/h1&gt;

&lt;p&gt;En esta parte conectaremos nuestro repositorio a Registries a fin de obtener la imagen Docker que posteriormente desplegaremos. &lt;/p&gt;

&lt;p&gt;Ingresamos al apartado pipelines de nuestro Azure DevOPS y crearemos una nueva&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FVRUjYZO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kqmq04vtrzi29sdmvlj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FVRUjYZO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kqmq04vtrzi29sdmvlj.png" alt="Image description" width="880" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Seleccionamos Azure Repos Git y posteriormente el proyecto con el que vamos a trabajar. En mi caso es testProject &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VN22rnd8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gmc836o6d9dcgjbkhbx4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VN22rnd8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gmc836o6d9dcgjbkhbx4.png" alt="Image description" width="674" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A continuación nos aparecerán las opciones disponibles, para esta entrada seleccionaremos la segunda opción de Docker (Build and Push and Image to Azure Container Registry)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uXDGJg8E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yjv5i1fxijrnypvdhmag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uXDGJg8E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yjv5i1fxijrnypvdhmag.png" alt="Image description" width="609" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora seleccionamos la subscripción en la que desplegaremos el contenedor. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uxItBrZy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ku52bwhhsud8e2qrix24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uxItBrZy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ku52bwhhsud8e2qrix24.png" alt="Image description" width="491" height="913"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En la siguiente pantalla vamos a validar a que registro enviaremos la imagen, así como también el nombre que llevará la imagen. Para este caso dejaré todo como aparece en el asistente y hacemos clic en el Validate and Configure &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f_d3HYGB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8b3njh9ekcn6qbrkfxyk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f_d3HYGB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8b3njh9ekcn6qbrkfxyk.png" alt="Image description" width="505" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En la siguiente pantalla nos aparecerá la pantalla del archivo de configuración del pipeline ya finalizado. Hacemos clic en Save and Run, damos commit y esperamos a que se ejecute el pipeline&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xp1TfAfU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zd2fk424z1wcn7btqa5c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xp1TfAfU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zd2fk424z1wcn7btqa5c.png" alt="Image description" width="740" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8GXUpB85--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hehovntwqo4rsjtrbejw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8GXUpB85--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hehovntwqo4rsjtrbejw.png" alt="Image description" width="740" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez que finalizó nuestro Pipeline, procedos a regresar al Registries. En el apartado Repositories podemos observar nuestra imagen desplegada. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QMeUnaqP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b63c3hykbn1w3wjdpx8u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QMeUnaqP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b63c3hykbn1w3wjdpx8u.png" alt="Image description" width="794" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Desplegando el contenedor a Azure Container App
&lt;/h1&gt;

&lt;p&gt;Para este apartado crearemos un nuevo recurso de tipo Azure Container App. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZseVOVE6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4dwnxs4it3tf0g5kd0hb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZseVOVE6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4dwnxs4it3tf0g5kd0hb.png" alt="Image description" width="839" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez creado el recurso, ingresamos y buscamos el apartado Containers. Probablemente tengamos el contenedor "hello-world", esto porque me he bricando un paso cuando estaba creando el recurso&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DWhf5e_h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s1korzg6konzutrscmz8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DWhf5e_h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s1korzg6konzutrscmz8.png" alt="Image description" width="288" height="758"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hacemos clic en Edit &lt;/p&gt;

&lt;p&gt;Nos aperecerá la siguiente ventana donde eliminaremos el contenedor de ejemplo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mIuPd3F4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8grqunjc1buquxmts7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mIuPd3F4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8grqunjc1buquxmts7m.png" alt="Image description" width="880" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hacemos clic en el botón Add (+) y nos aparecerá un cuadro de diálogo donde se deberá ingresar la información para conectar el contenedor que acabamos de desplegar en Registries &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qE8cW9jf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o85n4yrsoxnjqaqd0cst.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qE8cW9jf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o85n4yrsoxnjqaqd0cst.png" alt="Image description" width="553" height="769"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si nos aparece ese error es porque no tenemos permisos para leer las imagenes del Registro, para ello regresamos al Registro &lt;/p&gt;

&lt;p&gt;En el apartado Access Keys habilitamos la opción Admin user &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0sr9ULCj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1tbtnn7cd4ao4fpnuvow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0sr9ULCj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1tbtnn7cd4ao4fpnuvow.png" alt="Image description" width="880" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Te recomiendo guardar para uso futuro el password que aparece.&lt;/p&gt;

&lt;p&gt;Una vez realizado esta modificación regresamos al Container Apps y volvemos a agregar el contenedor. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bnAuXOUh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sxr0agzwsmiw4cu92kcu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bnAuXOUh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sxr0agzwsmiw4cu92kcu.png" alt="Image description" width="552" height="765"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora podemos tener acceso al registro y las imagenes de contenedor que este tiene. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RFzmAPHX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8b5dghbbiz7v7mghyl18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RFzmAPHX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8b5dghbbiz7v7mghyl18.png" alt="Image description" width="552" height="765"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Al final tienes un apartado Environment Variables, aquí configuras las variables de entorno de tu App, ejemplo conexión a base de datos, puertos, etc. &lt;/p&gt;

&lt;p&gt;Como este es un simple hola mundo, solo agregaré la variable de entorno PORT, que es la necesaria para que la app pueda funcionar. &lt;/p&gt;

&lt;p&gt;Finalizando las configuraciones hacemos clic en Add&lt;/p&gt;

&lt;p&gt;Con esto tendremos nuestra aplicación contenerizada desplegada en Azure Containers App. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lfOyuZm3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u2q9py6hbphh94ex6b6j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lfOyuZm3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u2q9py6hbphh94ex6b6j.png" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Probando el endpoint en Altair Graphql&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CNjQ5NJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jxx1zfruvmupsibd8qs8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CNjQ5NJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jxx1zfruvmupsibd8qs8.png" alt="Image description" width="880" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>containerapps</category>
      <category>tutorial</category>
      <category>graphql</category>
    </item>
    <item>
      <title>Un análisis de cómo vulneraron mi servidor de pruebas de PostgresSQL y cómo proteger tu </title>
      <dc:creator>Francisco Javier Guerrero Martinez</dc:creator>
      <pubDate>Mon, 20 Sep 2021 07:49:40 +0000</pubDate>
      <link>https://dev.to/diwolf/un-analisis-de-como-vulneraron-mi-servidor-de-pruebas-de-postgressql-y-como-proteger-tu-1m85</link>
      <guid>https://dev.to/diwolf/un-analisis-de-como-vulneraron-mi-servidor-de-pruebas-de-postgressql-y-como-proteger-tu-1m85</guid>
      <description>&lt;p&gt;&lt;em&gt;Un análisis de cómo vulneraron mi servidor de pruebas de PostgresSQL y cómo proteger tu instalación si eres nuevo con este motor de base de datos.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Recientemente inicié a trabajar con una base de datos PostgreSQL fuera del ambiente seguro de los contenedores, esto On Promise en un servidor virtual, ya se la saben primero hago explotar mis experimentos en casa y ya luego al mundo laboral.&lt;br&gt;
No han pasado menos de tres días que empecé y me había percatado de que la CPU estaba al máximo y se me creaban una serie procesos que consumían todos los núcleos. &lt;/p&gt;

&lt;p&gt;Sin comprender porque sucedía el día de hoy empecé a indagar por cuenta propia y descubrí una “vulnerabilidad” del propio gestor, &lt;strong&gt;&lt;em&gt;“PgMiner Botnet Attacks PostgreSQL”&lt;/em&gt;&lt;/strong&gt; hasta este punto debo reconocer lo noob que vengo siendo y el pecado de la inocencia, mi experiencia se desarrolla más en Percona con base MySQL.&lt;/p&gt;

&lt;p&gt;Después de estar leyendo diversos artículos de cómo deshacerme de este &lt;em&gt;“Malware”&lt;/em&gt; llegué a las entradas de &lt;em&gt;Sanchistsharman&lt;/em&gt; &lt;a href="https://dev.to/sanchitsharma/investigation-into-postgres-malware-hack-2ai0"&gt;&lt;strong&gt;Investigation into Postgres malware (hack?) - DEV Community&lt;/strong&gt;&lt;/a&gt;, pero antes de describir todo esto te explico. &lt;br&gt;
Siempre que instalo un nuevo servidor Linux por defecto va Glances and Htop para tener una vista más clara se los procesos que se están ejecutando. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UFW to Rescue&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;El proveedor actual no nos da un firewall administrable así que lo primero que realicé fue habilitar ufw, actualmente trabajo con Ubuntu Server 20.04.&lt;/p&gt;

&lt;p&gt;En este punto dejo abierto solo los puertos que requiero para administrar el servidor. &lt;br&gt;
Una vez aplicadas las reglas al firewall procedí a deshabilitar el logueo de usuario postgresql y revocar los accesos a las bases de datos. &lt;/p&gt;

&lt;p&gt;Como siguiente punto cambiar el puerto 5432 por uno diferente, esto lo recomiendo para todos los servicios a excepción de los puertos 80 y 443, el resto de los servicios puede ser cambiado. &lt;br&gt;
En este punto tanto el uso de la CPU como de la Memoria había disminuido. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LWJmt6J2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2mtz7mjl8nes3exwsi5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LWJmt6J2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2mtz7mjl8nes3exwsi5.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lo mismo de agradecido hasta ahora con las conexiones al servidor&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4jLNub8N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwgmrx3ws2z4397mo5xs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4jLNub8N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwgmrx3ws2z4397mo5xs.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Te recomiendo seguir esta guía &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-20-04-es"&gt;Cómo configurar un firewall con UFW en Ubuntu 20.04 | DigitalOcean&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Posteriormente regresando al post de Sanchistsharman me he puesto a leerlo todo y trate de entender el cómo lo había hecho. &lt;/p&gt;

&lt;p&gt;En mi caso particular estoy trabajando con la versión 12 del motor y el manual no funcionó como tal sin embargo al navegar en &lt;em&gt;/var/lib/postgresql/12&lt;/em&gt; había encontrado un &lt;strong&gt;“binario llamado k”&lt;/strong&gt; pero lo que el indicaba en el manual no. &lt;/p&gt;

&lt;p&gt;Retrocedí un directorio y ejecuté el comando ls -f para mostrar los archivos ocultos y me encontré con el siguiente archivo &lt;strong&gt;&lt;em&gt;.systemd-private-2OossFop8vSbHI1fjSzMJoolZfE29S.sh&lt;/em&gt;&lt;/strong&gt; cuyo contenido no es más que una cade hasheada a base 64&lt;/p&gt;

&lt;p&gt;A continuación la imagen&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---8WO3UTw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mtdgu6vtfoo69jnjpxgo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---8WO3UTw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mtdgu6vtfoo69jnjpxgo.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Acorde a lo que indica el post de sanchistsharma hay que navegar en los directorios del archivo ya desencriptado para removerlo.&lt;/p&gt;

&lt;p&gt;Después de una batalla de tres horas así luce nuevamente mi servidor de pruebas &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--31iHAWQs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydsuagxi00ij5qawkqgm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--31iHAWQs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydsuagxi00ij5qawkqgm.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusiones.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Después de esta vulnerabilidad recomendaría que, aunque tengas una instalación en Windows revisaras el estado de tus procesos (así sea para pruebas), si vas a trabajar con un servidor fuera de contenedores: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cambiar los puertos, deshabilitar el logueo para el usuario postgresql y crear otro rol que pueda administrar el motor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Utilizar una contraseña de más de 16 caracteres algo como wt2Ut/rF)asd3412-*--x~FZ.!*V((k4ry podría ayudar&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No dar por sentado que la instalación por defecto mitigará errores o vulnerabilidades, así sea la última versión. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linux es un sistema seguro, los errores los comete el administrador &lt;em&gt;sorry&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Aventurarse a trabajar y aprender cosas nuevas es divertido dentro de un entorno seguro, cuando vayas a producción asegúrate de haber aprendido todo y conocer realmente la tecnología que vas a implementar y sus vulnerabilidades, hoy lo aprendí a la mala. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Siempre pregúntate ¿qué pasó aquí? Y cómo poderlo resolver, recuerda que en producción se vuelve más complicado, ten ese espíritu de batalla e investigación. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Duerme a tus horas. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Referencias&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.caktusgroup.com/blog/2013/10/30/using-strace-debug-stuck-celery-tasks/"&gt;Using strace to Debug Stuck Celery Tasks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gbhackers.com/pgminer-botnet-postgresql/"&gt;PgMiner Botnet Attacks PostgreSQL Databases to Install a Cryptocurrency Miner&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://threatpost.com/pgminer-monero-mining-botnet/162209/"&gt;PGMiner, Innovative Monero-Mining Botnet, Surprises Researchers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9193"&gt;In PostgreSQL 9.3 through 11.2, the "COPY TO/FROM PROGRAM" function allows superusers and users in the 'pg_execute_server_program' group to execute arbitrary code in the context of the database's operating system user.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://security.netapp.com/advisory/ntap-20190502-0003/"&gt;CVE-2019-9193 PostgreSQL in NetApp Products&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://unit42.paloaltonetworks.com/pgminer-postgresql-cryptocurrency-mining-botnet/"&gt;PGMiner: New Cryptocurrency Mining Botnet Delivered via PostgreSQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=""&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>postgres</category>
      <category>pgminer</category>
    </item>
    <item>
      <title>Creando un API Microservicios con GraphQL + Apollo Gateway y MySQL</title>
      <dc:creator>Francisco Javier Guerrero Martinez</dc:creator>
      <pubDate>Sat, 11 Sep 2021 22:00:50 +0000</pubDate>
      <link>https://dev.to/diwolf/creando-un-api-microservicios-con-graphql-apollo-gateway-y-mysql-4gjc</link>
      <guid>https://dev.to/diwolf/creando-un-api-microservicios-con-graphql-apollo-gateway-y-mysql-4gjc</guid>
      <description>&lt;p&gt;Hace unos días que rondaba en mi cabeza el cómo poder diseñar una arquitectura basada en servicios utilizando el Stack que actualmente estoy aprendiendo "GraphQL + Apollo + NodeJS + TypeScript y MySQL" &lt;/p&gt;

&lt;p&gt;Evidentemente hasta ahora no había tenido necesidad de hacer algo parecido al menos no en mis anteriores proyectos, sin embargo todo nace por una necesidad "cómo podría optimizar los procesos de entrega en la página de RockandRo".&lt;/p&gt;

&lt;p&gt;Anteriormente había diseñado un API basada en REST, un monolito, sin embargo las necesidades del juego van cambiando así como las mías como cliente. &lt;/p&gt;

&lt;p&gt;En esta entrada realizaremos un pequeño ejercicio de un API basada en Microservicios utilizando GraphQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tabla de contenido
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;¿Qué es un microservicio?&lt;/li&gt;
&lt;li&gt;Problemática&lt;/li&gt;
&lt;li&gt;Codificando servicio proveedor&lt;/li&gt;
&lt;li&gt;Codificando servicio Gateway&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ¿Qué es un microservicio? &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Según la documentación proveída por Microsoft Azure define a los microservicios cómo "un método arquitectónico para crear aplicaciones donde cada función (o servicio) principal se compila e implementa de manera independiente". (Ref)&lt;/p&gt;

&lt;p&gt;Esto que significa en palabras "mortales", tu puedes definir tus propias funciones en diferentes lenguajes de programación en diferentes lenguajes de programación e ir agregando funcionalidad, así mismo si uno de los servicios llegase a fallar el resto podría seguir funcionando, gracias a que la arquitectura es distribuida y ligeramente acoplada, cosa que con un sistema basado en una arquitectura en Monolito causaría la detención del mismo. &lt;/p&gt;

&lt;h3&gt;
  
  
  Problemática  &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Nota: Utilizaré la palabra cliente para hacer referencia a la entidad o persona que contrató nuestros servicios.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;El cliente desea crear, obtener, modificar y eliminar la información de sus proveedores&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;¿Qué información desea almacenar el cliente de sus proveedores?&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Nombre del proveedor&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Representante de ventas&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Teléfono de contacto&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Correo Electrónico&lt;/em&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Codificando servicio proveedor &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Creando la base de datos
&lt;/h4&gt;

&lt;p&gt;Creamos una nueva base de datos, en mi caso la llamaré proveedores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;proveedores&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Posteriormente creamos la tabla con la información descrita en el apartado Problemática.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;proveedor&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nombreProveedor&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;representante&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;telefono&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;UNSIGNED&lt;/span&gt; &lt;span class="n"&gt;AUTO_INCREMENT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ya tenemos lo básico para iniciar. &lt;/p&gt;

&lt;h3&gt;
  
  
  Arquitectura de la aplicación
&lt;/h3&gt;

&lt;p&gt;En primera instancia vamos a crear el servicio &lt;em&gt;"proveedor" (service-proveedor)&lt;/em&gt; las dependencias que utilizaré serán las siguientes: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"@apollo/gateway": "^0.40.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"@graphql-tools/load-files": "^6.4.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"@wiicamp/graphql-merge-resolvers": "^2.1.2",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"apollo-server": "^3.0.2",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"apollo-server-core": "^3.0.2",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"apollo-server-express": "^3.1.2",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"dotenv": "^10.0.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"graphql": "^15.5.2",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"graphql-tools": "^8.2.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"mysql": "^2.18.1",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"mysql2": "^2.2.5",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"ts-node": "^10.0.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"ts-node-dev": "^1.1.1",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"typescript": "^4.3.5"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Dependencias de desarrollo&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"@types/express": "^4.17.12",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"@types/express-graphql": "^0.9.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"@types/graphql": "^14.5.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"@types/node": "^16.4.0"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Requerimientos funciones
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Crear un nuevo proveedor &lt;/li&gt;
&lt;li&gt;Editar la información de un proveedor &lt;/li&gt;
&lt;li&gt;Eliminar un proveedor de la base de datos&lt;/li&gt;
&lt;li&gt;Obtener la información de un proveedor &lt;/li&gt;
&lt;li&gt;Obtener la lista de proveedores&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Definición del archivo SQL_PROVEEDORES.ts
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;En este archivo definiremos las consultas a la base de datos que prácticamente son las reglas del negocio definidas en el apartado Requerimientos funcionales, este archivo tendrá el siguiente contenido.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Crear un proveedor&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CREARP_ROVEEDOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;INSERT INTO proveedor (nombreProveedor,representante,telefono,email) VALUES (?,?,?,?)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//editar proveedor&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EDITAR_PROVEEDOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPDATE SET nombreProveedor=?, representante=?, telefono=?, email=? SET WHERE id=?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//Eliminar proveedor&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DELETE_PROVEEDOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DELETE FROM proveedor WHERE id= ? &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//Listar proveedor&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SELECT_PROVEEDOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT  FROM proveedor WHERE id=? LIMIT 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//Listar todos los proveedores&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SELECT_ALL_PROVEEDORES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT  FROM proveedor &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creado esto, nos dirigimos a la carpeta config  donde crearé los siguientes dos archivos: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.env &lt;/li&gt;
&lt;li&gt;mysql.persistences.ts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En el archivo .env crearemos las variables de entorno&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NODE_ENV="DEVELOPMENT"
PORT="PUERTO_DONDE_ESCUCHARÁ_EL_SERVICIO"
MYSQL_HOST="IP/URL DEL SERVIDOR MYSQL"MYSQL_USER="USUARIO_DB"
MYSQL_PASSWORD="CONTRASEÑA_DB"
MYSQL_DB="nombre_de_la_base_de_datos"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora, en el archivo mysql.presistences.ts agregaremos el siguiente código, este código nos permitirá conectarnos con la base de datos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createPool&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mysql2/promise&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;createPool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MYSQL_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MYSQL_USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MYSQL_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MYSQL_DB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;decimalNumbers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ya que tenemos estos archivos creados, nos vamos a la carpeta Schema, donde crearemos el &lt;em&gt;schema&lt;/em&gt; proveedor, el cual quedará definido de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;obtenerProveedores&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Proveedor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;obtenerProveedor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Proveedor&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;addProveedor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proveedor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ProveedorInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;updateProveedor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proveedor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ProveedorInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;deleteProveedor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Proveedor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;nombreProveedor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;representante&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;telefono&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ProveedorInput&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;nombreProveedor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;representante&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;telefono&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Básicamente ya tenemos la estructura del servicio a continuación trabajaremos en la definición de los &lt;em&gt;resolvers&lt;/em&gt;, dentro de esta carpeta tenemos &lt;em&gt;mutation&lt;/em&gt; y &lt;em&gt;query&lt;/em&gt; que básicamente son las operaciones que realizará el servicio, mismas que fueron definidas anteriormente en las reglas del negocio. &lt;/p&gt;

&lt;p&gt;Inicialmente empezaré a trabajar en la carpeta &lt;em&gt;mutation&lt;/em&gt; en esta carpeta crearemos dos archivos nuevos: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;index.ts&lt;/em&gt; El cual "unirá" los archivos de mutaciones &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;proveedores.ts&lt;/em&gt; El cual contiene la definición de las reglas de negocio de &lt;em&gt;Agregar, Eliminar, Editar&lt;/em&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dentro del archivo &lt;em&gt;poveedores.ts&lt;/em&gt; definimos las siguientes funciones.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;CREAR_PROVEEDOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DELETE_PROVEEDOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;EDITAR_PROVEEDOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../sql/SQL_PROVEEDORES&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolverMutationProveedor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Mutation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//Agregar un nuevo proveedor a la base de datos&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;addProveedor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;proveedor&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;nombreProveedor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;representante&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;telefono&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;proveedor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;START TRANSACTION&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CREAR_PROVEEDOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="nx"&gt;nombreProveedor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;representante&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;telefono&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;COMMIT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Operación finalizada con éxito&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ROLLBACK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;//Actualizar la información del proveedor&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;updateProveedor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;proveedor&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;nombreProveedor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;representante&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;telefono&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;proveedor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;START TRANSACTION&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;EDITAR_PROVEEDOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="nx"&gt;nombreProveedor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;representante&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;telefono&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;COMMIT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Información actualizada correctamente&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;//Eliminar registro&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;deleteProveedor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;START TRANSACTION&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DELETE_PROVEEDOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;COMMIT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Registro eliminado&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ROLLBACK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;resolverMutationProveedor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dentro del archivos &lt;em&gt;index.ts&lt;/em&gt; definiremos las siguientes funciones.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GMR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@wiicamp/graphql-merge-resolvers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//Query&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;resolverMutationProveedor&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./proveedores&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolverMutation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;GMR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;resolverMutationProveedor&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;resolverMutation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A continuación definiremos el contenido de la carpeta &lt;em&gt;query&lt;/em&gt; al igual que &lt;em&gt;mutations&lt;/em&gt; esta tendrá dos archivos, uno llamado &lt;em&gt;index.ts&lt;/em&gt; donde uniremos los archivos de query a medida que nuestro servicio vaya creciendo y otro llamado &lt;em&gt;proveedores.ts&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Definiendo el archivo &lt;em&gt;proveedores.ts&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;SELECT_ALL_PROVEEDORES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;SELECT_PROVEEDOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./../../sql/SQL_PROVEEDORES&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolverQueryProveedor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;obtenerProveedores&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;__&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SELECT_ALL_PROVEEDORES&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;obtenerProveedor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SELECT_PROVEEDOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;resolverQueryProveedor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Definiendo nuestro archivo &lt;em&gt;index.ts&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GMR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@wiicamp/graphql-merge-resolvers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//Query&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;resolverQueryProveedor&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./proveedor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mainResolver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;GMR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;resolverQueryProveedor&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;mainResolver&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Básicamente hemos terminado con nuestro servicio de proveedores, lo único que falta es definir el archivos server.ts, el cual lucirá de la siguiente forma &lt;/p&gt;

&lt;p&gt;&lt;em&gt;server.ts&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MeK00tk3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9owumw7hgychpgsqeuju.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MeK00tk3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9owumw7hgychpgsqeuju.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Al final, la estructura de nuestro servicio lucirá de la siguiente manera. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JVk-aOD4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aaf9iqqbhqwe0y2518ul.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JVk-aOD4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aaf9iqqbhqwe0y2518ul.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Codificando servicio Gateway &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Este es mas sencillo de codificar. &lt;/p&gt;

&lt;p&gt;Dependencias &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"@apollo/gateway": "^0.41.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"apollo-server": "^3.3.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"dotenv": "^10.0.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"ts-node": "^10.0.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"graphql": "^15.5.2",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"typescript": "^4.3.5"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dependencias de desarollo&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"@types/graphql": "^14.5.0"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"@types/node": "^16.4.0",&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"ts-node-dev": "^1.1.1"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Creamos el archivo server.ts dentro de la carpeta src, el cual tendrá el siguiente contenido. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q-HSNrFF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s2uiyl88wr2nfwkjajeq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q-HSNrFF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s2uiyl88wr2nfwkjajeq.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Con esto tendremos funcionando un API basada en Microservicios utilizando GraphQL, MySQL y Apollo Gateway.&lt;/p&gt;

&lt;p&gt;Puedes acceder al repositorio del código fuente desde aquí &lt;a href="https://github.com/DiWolf/api-servicios-graphql"&gt;https://github.com/DiWolf/api-servicios-graphql&lt;/a&gt;&lt;/p&gt;

</description>
      <category>graphql</category>
    </item>
  </channel>
</rss>
