Feature Flags y cómo romper con cuidado

March 1, 2024

Este post es la versión escrita de la presentación que hice en el meetup de BeerJS Córdoba el 29 de febrero de 2024.

Feature Flags? Toggles? Switches?
Feature Flags? Toggles? Switches?
En este post voy a hablar de feature flags y de como implementarlas con Flagsmith en React. Es posible que hayas escuchado hablar de ellas con otros nombres como feature toggles, feature switches, etc. pero voy a intentar siempre referirme a ellas como feature flags para no confundir a nadie.

Dicho esto, vamos a lo que nos interesa.

¿Qué es un feature flag?

Un feature flag es basicamente una variable que se utiliza para controlar el comportamiento de un sistema. Se utilizan para habilitar o deshabilitar funcionalidades de un sistema sin tener que cambiar el código.

Tomando una de las clasificaciones que hace Martin Fowler, las feature flags pueden ser:

  • De release: permiten que bloques de código incompletos y no probados se envíen a producción como código (que tal vez nunca se encienda).
  • De operación: aquellas que se usan para controlar el comportamiento de nuestro sistema. Algunas de estas pueden permanecer casi indefinidamente.
  • De permisos: se utilizan para cambiar las características o la experiencia del producto que reciben ciertos usuarios. Puede ser el caso de usuarios premium, pruebas alfa, betas, etc.
  • De experimentación: las que se utilizan para realizar pruebas de variación o A/B testing.

Clasificaciones de feature flags
Clasificaciones de feature flags

Viendo esto a varios seguro ya se les ocurren varios casos de uso ademas de los que mencioné, asi que vamos a ver algunos de los casos de uso más comunes:

  • Control de features (comportamiento): para activar o desactivar características específicas de la aplicación sin necesidad de desplegar nuevo código. Esto permite, como ya mencioné, tener funcionalidades desarrolladas pero desactivadas en producción hasta que se decida su lanzamiento.

  • Pruebas alfa, beta: otro caso seria habilitar nuevas características solo para un grupo selecto de usuarios, como testers de alfas o betas.

  • Usuarios premium: esto sería para ofrecer características exclusivas a usuarios premium o suscriptores. Con un flag, podrias diferenciar la experiencia de usuario según su nivel de suscripción.

  • Rollback / Kill switch: también desactivar rápidamente una característica en producción en caso de que algo salga mal o se detectara un problema grave, sin necesidad de revertir el despliegue completo.

  • Pruebas en producción: podriamos activar características por entorno, facilitando las pruebas en entornos de producción de forma controlada, minimizando riesgos.

  • Canary releases: en esta logica de separar feature flags por grupos, podriamos habilitar nuevas funcionalidades solo a algunos usuarios especificos que decidamos. Esto podría permitir, por ejemplo, monitorear el comportamiento de usuarios dentro de la aplicación antes de desplegar en producción.

  • A/B Testing: tambien se pueden implementar pruebas A/B, donde diferentes grupos de usuarios ven diferentes versiones de una funcionalidad. Esto es bastante similar a los canary releases, pero en este caso se busca comparar el rendimiento de dos versiones de una funcionalidad.

Ahora, es importante tener en cuenta que las feature flags no son una solución mágica, no existen las balas de plata. Aplicadas sin controles, tienen la capacidad de generar deuda técnica por una de las caracteristicas por las que las separabamos en tipos, su longevidad.

Feature flags de longevidad mas corta, como pueden ser las de experimentacion o las de release, dejan de ser usadas al cabo de un tiempo. Esto significa que estas feature flags no solo generan trabajo al implementarlas sino tambien en la posterior limpieza de ese código.

Implementación

Existen muchas herramientas en el mercado para implementar feature flags. En este post, vamos a ver cómo implementar feature flags con Flagsmith, una herramienta que me gusta mucho y que he usado en varios proyectos personales.

Algunas de las opciones más usadas para implementar feature flags
Algunas de las opciones más usadas para implementar feature flags

Primero, algunos disclaimers:

  • Por qué Flagsmith? Porque es la herramienta que me parece mas fácil de usar y que pude, con menor cantidad de configuraciones, poner en marcha para mis proyectos personales.
  • Voy a levantar el servicio de Flagsmith de forma local, pero también se puede usar en la nube, para lo cual pueden consultar la versión SaaS de Flagsmith acá.
  • No estoy sponsoreado por Flagsmith ni por ningún otra empresa.

Dicho todo lo previo, vamos a la implementación!

Requisitos previos

  • Docker
  • Docker Compose

Implementación con Flagsmith

  1. Vamos a dirigirnos al repositorio de Github de Flagsmith y vamos a seguir los pasos para clonar el docker-compose que proveen en el repositorio. Para esto podemos ejecutar los siguientes comandos:
curl -o docker-compose.yml https://raw.githubusercontent.com/Flagsmith/flagsmith/main/docker-compose.yml docker-compose -f docker-compose.yml up
  1. Luego de ejecutar estos comandos, vamos a ver en los logs de la terminal que se nos va a mostrar un mensaje similar a este:
Superuser "admin@example.com" created successfully. Please go to the following page and choose a password: http://localhost:8000/password-reset/confirm/.../...
  1. Vamos a dirigirnos a la URL que nos muestra en la terminal y vamos a setear una contraseña para el usuario admin.

  2. Luego de setear la contraseña, nos dirigiremos a la URL del servicio, en mi caso http://localhost:8000, y vamos a loguearnos con el usuario admin y la contraseña que seteamos.

  3. Una vez logueados, veremos la pantalla principal de Flagsmith, donde podemos crear un nuevo proyecto desde el botón "Create Project", completando los datos del proyecto.

Pantalla de creación de proyecto en Flagsmith
Pantalla de creación de proyecto en Flagsmith

  1. Debemos configurar un entorno para nuestro proyecto desde "Create Environment" y vamos a completar los datos del entorno.

Pantalla de creación de entorno en Flagsmith
Pantalla de creación de entorno en Flagsmith

  1. Una vez creado el entorno podemos comenzar a crear nuestras flags y a consumirlas en nuestra aplicación.

Consumir flags en nuestra aplicación

Dependiendo del lenguaje y el framework que estemos utilizando, la forma de consumir las flags puede variar. Existe una variedad de SDKs para diferentes proveedores, lenguajes y frameworks (incluso una API REST), que nos permiten consumir las flags de Flagsmith de forma sencilla.

Algunas de las opciones que tenemos son SDKs para Frameworks de Javascript como React, Vue o Angular, React Native, Android (Kotlin), iOS (Swift), Node.js, Python, Ruby, Java, Go y más.

Pueden consultar la documentación de Flagsmith para ver cómo consumir las flags en su lenguaje y framework de preferencia. En este post, vamos a ver un ejemplo de cómo consumir las flags en una aplicación de React.

Ejemplo de uso en React

Lo primero que vamos a hacer es instalar el SDK de Flagsmith para React. Para instalarlo, podemos utilizar nuestro package manager de preferencia, en este caso voy a usar NPM:

npm i flagsmith --save

Luego, vamos a envolver nuestra aplicación con el componente FlagsmithProvider, pasándole la environment key de nuestro proyecto de Flagsmith y la URL a la que accedimos cuando levantamos el servicio de Flagsmith.

import flagsmith from 'flagsmith' import { FlagsmithProvider } from 'flagsmith/react' export function Root() { <FlagsmithProvider options={{ api: "NUESTRA URL DE FLAGSMITH", environmentID: "NUESTRA ENVIRONMENT KEY", }} flagsmith={flagsmith}> <App /> </FlagsmithProvider> };

Para obtener nuestra environment key, podemos dirigirnos a la sección de "Settings" de nuestro proyecto en Flagsmith y copiar la environment key de nuestro entorno desde la tab "SDK Keys".

Environment key en Flagsmith
Environment key en Flagsmith

Y finalmente, podemos utilizar el hook useFlags para obtener el valor de una flag:

import { useFlags } from 'flagsmith/react'; export function App() { const flags = useFlags(['show_locale_switcher'], ['design_v2']); // Podemos usar el estado de la flag para mostrar o no el componente const showLocaleSwitcher = flags.show_locale_switcher.enabled; // E incluso el valor de la flag para setear el idioma de la aplicación const locale = flags.show_locale_switcher.value; return ( <div> {/* Un buen ejemplo es el caso de la internacionalización de aplicación */} {showLocaleSwitcher && <LocaleSwitcher defaultValue={locale} />} {/* Otro ejemplo podría ser el caso de un nuevo diseño */} {flags.design_v2.value? <LayoutV2 /> : <Layout />} </div> ); }

Al realizar cambios desde la interfaz de Flagsmith, provocamos un re-renderizado se actualizandose los valores de las flags en tiempo real.

Conclusión

Las feature flags son una herramienta muy útil para controlar el comportamiento de nuestro sistema y para separar releases de deploys. Nos permiten habilitar o deshabilitar funcionalidades de un sistema sin tener que cambiar el código y nos permiten realizar pruebas en producción de forma controlada, minimizando riesgos.

Existen muchas herramientas en el mercado para implementar feature flags, algunas de las cuales mencioné en este post. En este caso, vimos cómo implementar feature flags con Flagsmith, una herramienta que me gusta mucho y que he usado en varios proyectos personales.

Para cerrar, algunos articulos de la pagina de Martin Fowler y de la documentacion de Trunk Based Development que estan interesantes sobre estos temas y donde se habla tambien más profundamente.

Referencias

Este post fue escrito en base a los siguientes recursos:

Documentación del ejemplo de Flagsmith