ICM / how-to-do / Implementar una puerta de enlace con .NET Core y Ocelot – Parte I

Implementar una puerta de enlace con .NET Core y Ocelot – Parte I

27 enero 2022 | Miguel Díaz

En esta entrada y en la siguiente, vamos a hablar de arquitectura de microservicios y cómo podemos implementar una parte de enlace con .NET Core y Ocelot.

¿Qué es un microservicio?

Podemos definir un microservicio como un software especializado en una tarea, y que está diseñado para poderse comunicar y trabajar con otros microservicios de forma independiente.

Es difícil dar una definición muy exacta, pero podemos explicar que los microservicios aparecen como opuesto a los servicios de software monolíticos, aquellos que contienen todas sus partes necesarias en un mismo sistema. Y, además, ofrecen algunas ventajas sobre estos, como su escalabilidad, que se pueden desarrollar individualmente, que son fáciles de implementar y al ser especializados se pueden reutilizar.

¿Qué es Ocelot?

Con los microservicios aparece la necesidad de gestionar el tráfico, la seguridad y disponibilidad entre ellos, también surge un software que se encarga de hacer estas funciones: los llamados API Gateways. Uno de estos softwares es Ocelot, que se puede instalar como paquete NuGet e implementar en proyectos .NET.

Este sería un esquema de la relación entre la aplicación cliente de los microservicios y los propios microservicios. El Gateway es el paso intermedio entre ambos y facilita las funciones que hemos dicho, además de muchas otras.

ocelot gateway

Implementación Gateway Ocelot

Vamos a implementar un gateway de Ocelot de forma simplificada con un par de microservicios, lo mínimo para un ejemplo funcional. Vemos a crear tres proyectos de ASP.NET Core Web API con la versión .NET CORE 5.0. Estos emulan una tienda, donde existirían dos servicios diferentes: uno que provee los productos y otro a los usuarios de la tienda.

De esta forma, tendremos el siguiente esquema:

ocelot gateway

Creación proyectos

Para crear los proyectos, vamos a seguir los siguientes pasos en Visual Studio: Crear Nuevo Proyecto -> C# ASP.NET Core Web API.

nuevo proyecto

Escogemos el nombre para el proyecto:

new project

Establecemos como versión de Framework .NET 5.0, y deshabilitamos el apartado de Configure for HTTPS. Para este ejemplo lo vamos a hacer solo por http.

gateway oceolet

Repetimos el mismo proceso para los otros dos proyectos restantes, añadiéndolos a la solución y con los mismos valores en la configuración.

gateway ocelot

Esto es lo que debería aparecer en el explorador de soluciones, una vez hemos creado todos los proyectos. Podemos observar que se han generado los archivos WeatherForecast.cs. Son los ejemplos que se forman por defecto, así que los podemos eliminar.

ejemplos

Creación modelos de datos

Como siguiente paso, vamos a ejecutar los modelos de datos para los dos microservicios. Estos van a contener los datos que se transmiten en las peticiones a la API, y en nuestro ejemplo simplificado van a ser solo unas variables simples.

Modelo Usuario

Para crear el modelo, seleccionamos la raíz del proyecto Tienda.Usuario y hacemos Click derecho -> Add -> New File y seleccionamos una Clase, a la que llamaremos UsuarioModel.cs

modelo de usuario

La clase va a contener el siguiente código: cuatro propiedades que representan un id, en nombre y apellido del usuario y su correo.

modelo trabajo ocelot

namespace Tienda.Usuario
{
    public class UsuarioModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
    }
}
Modelo Producto

Hacemos el mismo proceso para añadir una clase ProductoModel.cs, esta vez en la raíz del proyecto Tienda.Producto.

Esta clase va a contener las propiedades para el id, nombre, cantidad en stock y precio por unidad de cada producto.

modelo producto ocelot

namespace Tienda.Producto
{
    public class ProductoModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int CantidadStock  { get; set; }
        public double PrecioUnidad { get; set; }
    }
}

Creación controladores

Una vez creado los modelos, podemos añadir los controladores, que es el código que se ejecuta al recibir peticiones HTTP.

Los añadimos dentro de la carpeta Controllers de cada proyecto de API, haciendo Click Derecho -> Add -> Controller, y seleccionamos MVC Controller – EMPTY.

controllers

ocelot

Vamos a crear primero el controlador para Producto y lo llamamos  ProductoController.cs.

ocelot

Este es el código que usaremos para este controlador, maneja únicamente las peticiones de tipo GET. Dentro de la función declaramos dos objetos de tipo producto y daremos valores a sus propiedades. Estos datos van a ser los que devuelve la API al hacer una petición a /api/Producto.

tienda controllers

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

namespace Tienda.Producto.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductoController : ControllerBase
    {
        [HttpGet]
        public IEnumerable<ProductoModel> Get()
        {
            ProductoModel producto1 = new ProductoModel();
            producto1.Name = "Botijo barro";
            producto1.Id = 1;
            producto1.CantidadStock = 100;
            producto1.PrecioUnidad = 10.50;
            ProductoModel producto2 = new ProductoModel();
            producto2.Name = "Botijo arcilla";
            producto2.Id = 2;
            producto2.CantidadStock = 25;
            producto2.PrecioUnidad = 13.25;
            return new List<ProductoModel> { producto1, producto2 };
        }
    }
}

Repetimos lo mismo para el caso de Usuario, creando un controlador de la misma manera en su proyecto, y añadimos el siguiente código. Tiene la misma utilidad que para el de Producto, declaramos y rellenamos los datos para dos Usuarios, que se devuelven en las peticiones GET.

usuario tienda

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

namespace Tienda.Usuario.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UsuarioController : ControllerBase
    {
        [HttpGet]
        public IEnumerable<UsuarioModel> Get()
        {
            UsuarioModel usuario1 = new UsuarioModel();
            usuario1.Name = "Alice";
            usuario1.LastName = "Smith";
            usuario1.Id = 1;
            usuario1.Email = "alice@icm.es";
            UsuarioModel usuario2 = new UsuarioModel();
            usuario2.Name = "Bob";
            usuario2.LastName = "Johnson";
            usuario2.Id = 2;
            usuario2.Email = "Bob@icm.es";
            return new List<UsuarioModel> { usuario1, usuario2 };
        }
    }
}

Comprobación funcionamiento APIs

Una vez completado el código de los controladores, podemos ejecutar las APIs y comprobar su funcionamiento. En las propiedades de la Solución, modificamos las opciones para que se inicien todas las APIs al hacer debug. Y las ejecutamos todas a la vez:

apis

En las propiedades de cada proyecto también podemos observar que puertos va a usar cada aplicación, y modificarlos en caso que sea necesario. En nuestro caso usamos los siguientes:

Aplicación Dirección
Tienda http://localhost:57123
Tienda.Producto http://localhost:56023
Tienda.Usuario http://localhost:36402

Pasamos a hacer las peticiones a los controladores para cada API. Para ello, vamos a utilizar el software Postman, pero es posible hacer esto mismo desde algún navegador. La Petición a la API de Tienda.Producto, nos devuelve los datos que hemos establecido antes para cada instancia de Producto.

local host

Hacemos lo mismo para Usuario, con su dirección y puerto correspondiente, y obtenemos las propiedades de cada uno de los usuarios.

local host usuario

En la siguiente entrada, os explicaremos cómo proseguir con el proyecto y configurar Ocelot.