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.
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.
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.
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
- 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
- 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/.../...
-
Vamos a dirigirnos a la URL que nos muestra en la terminal y vamos a setear una contraseña para el usuario admin.
-
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.
-
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.
- Debemos configurar un entorno para nuestro proyecto desde "Create Environment" y vamos a completar los datos del entorno.
- 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".
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:
- Trunk Based Development - Feature Flags
- Martin Fowler - Feature Flags
- Martin Fowler - Feature Toggles