.NET

App Configuration con refresco dinámico de settings

App Configuration es un servicio muy potente de Azure que nos permite manejar las configuraciones de nuestra aplicación desde la nube. Nos permite definir settings por clave-valor, asignar labels que diferencian su valor entre los posibles entornos de nuestra aplicación e incluso da soporte para aplicar A/B testing a través de su feature manager.

En este post veremos cómo integrar App Configuration con en una API en .NET 6, cómo configurarlo para poder refrescar las settings de la aplicación en tiempo real y qué buenas prácticas debemos seguir para hacerlo. ¡Vamos a ello!

Paso a paso

En primer lugar, partamos de una base. En este repositorio de github dejo la aplicación ya terminada, por si quieres ver directamente el resultado final. También tienes la opción de ir haciendo el paso a paso conmigo si te apetece, descargándote el código y yendo a la rama “fresh-app”, desde donde empezaremos a configurar todo.

Tenemos una solución con tres proyectos, uno de API y dos de clases, donde iremos dejando nuestro código de manera ordenada.

Ahora, vamos al portal de Azure y creamos el App Config que usaremos para dar de alta las settings de nuestra aplicación. Te dejo el link a la documentación oficial de Microsoft que tiene un paso a paso de cómo hacer este proceso.

Una vez tengamos nuestro App Config listo, vamos a crear dos claves. En la sección configuration explorer añadiremos la clave “Settings:HelloWorld” que tendrá el valor “Hola mundo!” y la clave “Sentinel” que tendrá el valor “False”.

Tras esto, iremos a la sección de Access keys y copiaremos nuestra cadena de conexión para usarla en nuestra aplicación.

Y la pegaremos en nuestro archivo “appsettings.Development.json” de tal manera que quede así.

Siguiente paso: añadir el paquete nuget “Microsoft.Azure.AppConfiguration.AspNetCore” a nuestro proyecto de API y empezar a configurarlo todo.

En nuestro Program.cs añadiremos lo siguiente:

Vamos a analizar esta configuración por partes.

“builder.Configuration.AddAzureAppConfiguration”, configura nuestra aplicación para conectarse al App Config de Azure.

  • Haciendo ese “.Select()” le estamos diciendo que recupere todas las claves almacenadas sin importar su key o etiqueta.
  • Con el método “ConfigureRefresh” le indicamos que se ponga a la escucha de nuestra clave “Sentinel”. Cuando esta clave cambie de valor, hará que nuestra aplicación refresque los valores de las settings y obtendrá la configuración más reciente.
  • Además, en el método “.SetCacheExpiration()” hemos configurado un intervalo de tiempo para tener cacheadas las claves. Con eso, hasta que la caché no expire, no intentará refrescar nuevamente las settings de nuestra aplicación.

“builder.Services.AddAzureAppConfiguration()” añade el middleware de App Configuration a la colección de servicios de nuestra aplicación.

Y “app.UseAzureAppConfiguration()” habilita que nuestra aplicación use el middleware para refrescar la configuración automáticamente.

En este punto, me gustaría detenerme para explicar más en detalle cómo funciona el proceso de refresco de las settings.

¿Cómo funciona el refresco de las settings?

Con cada llamada que recibe nuestra API, se activa el middleware e intenta actualizar las claves de nuestra aplicación. Lo primero que hace es comprobar si la caché de las claves ha expirado (por eso se la hemos configurado con tan poco tiempo de vida en el ejemplo, para poder ver los cambios de manera rápida).

Si nuestra caché está vigente, devolverá los valores que ya tiene almacenados. En caso de que nuestra caché haya expirado, lanza una llamada contra App Configuration de Azure preguntando por el valor de la clave que está trackeando. Esta clave suele contener la palabra “Sentinel” por convención, y solo cuando el valor de la clave ha cambiado, hace una nueva petición para recuperar las claves que tiene configuradas en el método “.Select()”.

Ahora que ya tenemos un poco más claro cómo funciona el refresco de las settings, sigamos configurando nuestra aplicación.


En el proyecto “ReloadableSettings.Models” vamos a añadir una clase llamada “Settings”. En esta clase  volcaremos los valores de nuestras settings para consumirlos posteriormente en más partes de la aplicación.

En el proyecto “ReloadableSettings.Api” creamos una nueva carpeta “Extensions”, en la que añadiremos una clase estática llamada “ConfigureServicesExtensions” para añadir métodos de extensión que nos ayuden a configurar nuestra aplicación.

Vamos a crear el método “ConfigureSettings”, con el que registramos las settings de la aplicación, y así, poder consumirlas posteriormente a través del patrón TOptions

Y ahora, llamamos al método desde nuestro Program.cs

Con todo esto, ya estamos listos para empezar a hacer uso de nuestros valores de configuración.

Vamos a crear un servicio que nos devuelva nuestras settings, llamado “Settings Service” en el proyecto “ReloadableSettings.Services”.


En este servicio hacemos uso de la interfaz IOptionsSnapshot para inyectar la dependencia de las settings. Luego, creamos un método para devolver el valor de nuestra setting “HelloWorld”.

Ahora, vamos a registrar nuestro servicio en la inyección de dependencias del proyecto.

Y por último, creamos un nuevo controller que nos devuelva el valor de nuestras setting. Con este controller vamos a comprobar que el valor se refresca en tiempo real.

¡Vamos a probar!

Arrancamos nuestra API y hacemos una petición al endpoint para ver el valor actual de nuestra setting.

¡Genial! Ya estamos consumiendo nuestras settings desde App Config. Ahora, vamos a Azure, cambiamos el valor de la clave de Sentinel en nuestro app config,  y…

¡Tachán! Ya estamos viendo cómo nuestras settings se refrescan en tiempo real. ¡Todo ha salido a pedir de boca!

Buenas prácticas al trabajar con App Configuration

Hablemos un poco de buenas prácticas a la hora de trabajar con App Configuration.

Es recomendable que si trabajamos en un escenario en el que múltiples aplicaciones se conectan a nuestro App Configuration, tengamos claves separadas para cada una de las aplicaciones. Es un poco más complejo de mantener, pero con ello te aseguras de que las settings no se actualizan en una aplicación hasta el momento en el que lo deseas.

Si bien es cierto que el valor de la clave Sentinel no es importante, yo recomendaría que guarde algún tipo de formato en función de la versión de la aplicación o de la fecha. De esta forma, podemos establecer una relación sobre cuándo fue la última vez que se hizo un refresco de las settings.

Es recomendable también, pararse un rato a analizar el tiempo de expiración de caché que queremos establecer. App Configuration tiene un límite de 1000 peticiones al día en su capa gratis, y de 30.000 a la hora en el plan standart, tras lo cual empieza a devolver errores 429 (Too many requests). Si dejamos la tasa de refresco por defecto de treinta segundos, tenemos que estar seguros de que no va a dar problemas en nuestro contexto de trabajo.

En este post hemos utilizado la interfaz IOptionsSnapshot para recuperar las settings, pero no es la única manera de hacerlo. El patrón TOptions nos expone tres interfaces de las que hacer uso:

  • TOptionsSnapshot, pensada para ser usada en dependencias de tipo transient o scoped.
  • TOptionsMonitor, ideal para ser usada en dependencias de tipo singleton.
  • TOptions,  pensada para ser usada en dependencias de tipo singleton, pero que no es capaz de refrescar en tiempo de ejecución las settings. Es necesario reiniciar la aplicación para actualizar los valores.

Cuando vayamos a usar el patrón TOptions es bueno que averigüemos en qué tipo de dependencia estamos, y así utilizar la interfaz que más se adecue a nuestras necesidades.

Recapitulando

Hagamos un repaso final de lo que hemos visto en el post.

  1. Hemos añadido paso a paso el servicio App Configuration a nuestra aplicación.
  2. Hemos hablado sobre cómo funciona el sistema de refresco de App Configuration.
  3. Hemos usado el patrón TOptions para recuperar las settings de nuestra aplicación.
  4. Hemos hecho una prueba para ver cómo los valores de las settings cambian en tiempo real.
  5. Y finalmente hemos hablado de buenas prácticas a la hora de implementar App Configuration en nuestras aplicaciones.

Espero que este post te haya resultado interesante y útil, y ojalá que te haya dejado con ganas de aprender más.

En un futuro escribiré otro artículo relacionado, hablando de otra de las funcionalidades que tiene App Configuration, el Feature Manager.

¡Un saludo y hasta la próxima!

Bibliografía y referencias

Compartir
Publicado por
Andrés Sánchez Robleño

Este sitio web utiliza cookies para que tengas la mejor experiencia de usuario. Si continuas navegando, estás dando tu consentimiento para aceptar las cookies y también nuestra política de cookies (esperemos que no te empaches con tanta cookie 😊)