Patrón API Gateway

A la hora de crear servicios distribuidos vamos a crear múltiples servicios, estos se llamarán cada uno de una forma, en direcciones o con dominios distintos. 

 

Realizar estas acciones puede ser un follon, ya que si el sistema crece mucho, son muchos nombres que recordar, muchas direcciones que memorizar y lo que es peor, muchas actualizaciones que debemos mandar a nuestros clientes con mensajes como el siguiente: “la dirección ha cambiado de X a Y” o “Un nuevo servicio se a incluido en la dirección X” (la cual es diferente de Y).

Para evitar toda esta comunicación que puede llegar a una confusión, disponemos de la API Gateway.

 

 

1 - Qué es una API Gateway?

Una API Gateway es una capa extra que añadimos entre ya bien sean nuestro servicios Front End, o clientes externos para que se comuniquen con ella en vez de con el servicio Back end correspondiente.

 

Una API Gateway actúa como un reverse proxy al que podemos incluir funcionalidades extra, como pueden ser seguridad, políticas de uso, alertas, etc.

En nuestra aplicación de Distribt las API Gateway van a estar ubicadas tanto en la de acceso privado como en la de acceso público para clientes externos.

arquitectura api gateway

NOTA: Técnicamente podría ser la misma API Gateway, pero separaremos ambos conceptos para ver casos de uso específicos. 

 

1.1 - Cuándo utilizar API Gateway?

Como hemos mencionado algunos de los beneficios de utilizar API Gateway es centralizar el lugar donde se van a hacer dichas llamadas por parte tanto de clientes como de servicios.

 

Además nos permite introducir funcionalidades como: 

  • Autenticación: el primer filtro de seguridad para el control de acceso.
  • Rate Limiting: Significa controlar la cantidad de datos que los clientes pueden utilizar/descargar para así evitar un abuso, o por ejemplo si damos un servicio SaaS nos permite implementar un mayor control con la facturación a dicho cliente. Por ejemplo: las primeras 10 mil llamadas a la api son gratis y luego 2€ por cada mil llamadas adicionales.
  • Monitorizar las API: todo centralizado hace que sea mas sencillo monitorizar y saber que es lo que más se utiliza y como.
  • Si cambias un servicio, no necesitas notificar a los clientes, siempre y cuando no cambies el contrato de la API Gateway, ya que el cliente seguirá llamando a la Gateway mientras que la gateway hará la redirección al nuevo servicio.
  • Hay muchas más, como caché, load balancers, etc

 

 

2 - Implementación de API Gateway

Cuando creamos un sistema distribuido y tenemos varias opciones que elegir. Actualmente tenemos opciones muy conocidas como puede ser ocelot que dentro del entorno .NET es yo creo la más conocida. 

Alternativamente tenemos opciones como Ambassador o la que utilizo en este blog nginx.

opciones api gateways

Alternativamente, si estamos utilizando un proveedor de servicios en la nube como puede ser AWS o Azure ten en cuenta que ellos tienen sus propias api gateways ya implementadas en su sistema y que por un módico precio puedes adoptar.

  • Amazon API Gateway (AWS)
  • Azure API Management (Azure)
  • API Gateway (Google cloud)

 

2.1 - Implementación de una API Gateway en .NET con YARP

Si queremos que nuestra aplicación sea vendor free no podemos utilizar ninguna de las que vienen del proveedor de servicios, por lo que deberemos elegir un servicio que nos permita ser desplegado como una aplicación normal.

 

En este caso he elegido YARP (yet another reverse proxy), el cual fue presentado en la netconf de 2021 y es completamente open source

Además otra de las ventajas es que viene con bastantes funcionalidades ya implementadas como CORS, balanceadores de carga o mapeo en las rutas.

Finalmente, su documentación es muy completa.

 

 

3 - Creación de una API Gateway con YARP

Como he indicado, la idea principal de la API gateway es hacer de proxy inverso, pero con una mayor funcionalidad, para ello vamos a utilizar YARP.

 

Lo primero que vamos a hacer es ubicar nuestros microservicios en direcciones url conocidas. Me explico, cuando creas un proyecto las url con el puerto se asignan de forma aleatoria, lo que vamos a hacer aquí es asignarles un valor fijo y reconocible.

 

Para ello vamos al fichero lauchnsettings.json y modificamos el perfil Distrib.Services.XXX donde XXX es el microservicio a modificar; y modificamos el elemento applicationUrl con los siguientes valores.

  • Email: https://localhost:50120;http://localhost:50110
  • Orders: https://localhost:50220;http://localhost:50210
  • Products: https://localhost:50320;http://localhost:50310
  • Subscriptions: https://localhost:50420;http://localhost:50410

Nota: En caso de que quieras ejecutar las aplicaciones a través del perfil de ISSExpress, ten en cuenta que el puerto ssl debe estar entre el 44300 y el 443900.

 

Una vez tenemos las direcciones asignadas, pasamos a instalar el paquete Yarp.ReverseProxy desde nuget.

 

Una vez instalado, podremos aplicar a nuestro IServiceCollection de la API el método .AddReverseProxy().LoadFromConfig() Y como el nombre indica, vamos a cargar la configuración desde el fichero appsettings haciendo a la sección correspondiente.

 

Recuerda que creamos una abstracción para reducir el tamaño de nuestro código, por lo tanto, vamos a utilizar el delegado Action<WebApplicationBuilder> para pasar dicha información:

WebApplication app = DefaultDistribtWebApplication.Create(webappBuilder =>
{
    webappBuilder.Services.AddReverseProxy()
        .LoadFromConfig(webappBuilder.Configuration.GetSection("ReverseProxy"));
});

Y además

app.MapReverseProxy();

Alternativamente podemos crear una abstracción, pero en este caso no lo veo necesario al 100% ya que es una única línea de código. 

 

Ahora debemos configurar la sección ReverseProxy en nuestro fichero de configuración. Para ello utilizaremos la documentación oficial que nos proporciona YARP y veremos que es muy sencillo de hacer.

 

Un ejemplo básico de la configuración luce como el siguiente:

"ReverseProxy": {
    "Routes": {
      "OrderRoute": {
        "ClusterId": "OrderCluster",
        "Match": {
          "Path": "order-ms/{**catch-all}"
        },
        "Transforms": [
          {
            "PathPattern": "{**catch-all}"
          }
        ]
      },
      "ProductRoute": {
        "ClusterId": "ProductCluster",
        "Match": {
          "Path": "product-ms/{**catch-all}"
        },
        "Transforms": [
          {
            "PathPattern": "{**catch-all}"
          }
        ]
      }
    },
    "Clusters": {
      "OrderCluster": {
        "Destinations": {
          "OrderCluster/destination1": {
            "Address": "https://localhost:50220/"
          }
        }
      },
      "ProductCluster": {
        "Destinations": {
          "ProductCluster/destination1": {
            "Address": "https://localhost:50320/"
          }
        }
      }      
    }
  }

Dentro de la configuración podemos encontrar dos secciones clave: 

 

Rotues: 

Sección que describe una serie de rutas que van a ser comparadas cuando llega una request a la API.

Cuando definimos una ruta la asignamos a un cluster (que contiene la URL a la que hace referencia) y además le indicamos un patrón de URL para hacer match cuando llega una llamada a nuestra API Gateway.

  • {**catch-all} Como habrás podido observar, hay una especie de código raro, este código es la parte de la URL que el proxy va a recoger y reenviar a la dirección URL real; Y esta acción se realiza gracias a la sección PathPattern.

Clusters 

Sección que describe los endpoints a los que van asociadas nuestras requests. Los cuales están agrupados por nombre.

  • Destinations: Dirección URL asignada, un punto importante a tener en cuenta es que si introducimos más de un destino, YARP actuará también como balanceador de carga.

 

Para el ejemplo que acabamos de ver, cuando recibimos una llamada a la url de nuestra API Gateway http://localhost:7022/order-ms/order/3fa85f64-5717-4562-b3fc-2c963f66afa6 esta se redirecciona internamente a https://localhost:50220/order/3fa85f64-5717-4562-b3fc-2c963f66afa6 . Como puedes observar la sección order-ms/ ha sido ignorada.

 

Y lo podemos ver en la consola de la aplicación, si hacemos la llamada https://localhost:7022/order-ms/order/3fa85f64-5717-4562-b3fc-2c963f66afa6 veremos el siguiente mensaje:

info: Yarp.ReverseProxy.Forwarder.HttpForwarder[9]
      Proxying to https://localhost:50220/order/3fa85f64-5717-4562-b3fc-2c963f66afa6 HTTP
/2 RequestVersionOrLower no-streaming

 

 

Conclusión

  • En este post hemos visto que es una API Gateway y cuando utilizarla.
  • Además hemos visto cómo implementar API Gateway en .NET utilizando YARP.

 

 

Si quieres aprender más sobre los mismos no olvides seguir la web a través del RSS, o al canal de youtube, donde subiré los vídeos sobre cada uno de los aspectos. 

 

 

 


Uso del bloqueador de anuncios adblock

Hola!

Primero de todo bienvenido a la web de NetMentor donde podrás aprender programación en C# y .NET desde un nivel de principiante hasta más avanzado.


Yo entiendo que utilices un bloqueador de anuncios como AdBlock, Ublock o el propio navegador Brave. Pero te tengo que pedir por favor que desactives el bloqueador para esta web.


Intento personalmente no poner mucha publicidad, la justa para pagar el servidor y por supuesto que no sea intrusiva; Si pese a ello piensas que es intrusiva siempre me puedes escribir por privado o por Twitter a @NetMentorTW.


Si ya lo has desactivado, por favor recarga la página.


Un saludo y muchas gracias por tu colaboración

© copyright 2024 NetMentor | Todos los derechos reservados | RSS Feed

Buy me a coffee Invitame a un café