Tu equipo móvil está construyendo una página de producto. La API de propósito general devuelve decenas de campos que el teléfono nunca muestra, y las reseñas, el stock y la lista de deseos necesitan cada uno otra llamada. Cada cambio en esos endpoints espera a un equipo de API que también sirve al sitio web y a tres socios.
Un backend for frontend (BFF) da a cada experiencia de cliente su propia API pequeña del lado del servidor, a cargo del equipo que construye el cliente. Este artículo cubre el origen del patrón, qué debe hacer un BFF, cómo se compara con un API gateway y GraphQL, cómo mantiene los tokens OAuth fuera del navegador, sus trampas y cómo dibujarlo.
De dónde viene el patrón
SoundCloud le puso nombre al patrón. El artículo de Phil Calçado de 2015 describe aplicaciones construidas sobre la API pública, donde una página de perfil llamaba a /tracks/1234.json, /tracks/1234/related.json, /users/86762.json y /users/me.json y combinaba los resultados por su cuenta. Cuando los equipos de cliente pasaron a ser dueños de sus backends, trasladaron allí la combinación y la aplicación pedía GET /user-profile/123.json. El líder técnico web, Nick Fisher, acuñó el término. Calçado lo resume así: «El BFF era parte de la aplicación».
El artículo Backends For Frontends de Sam Newman, de noviembre de 2015, lo generalizó: un backend por experiencia de usuario, mantenido por el equipo que construye esa interfaz.
Clientes charlatanes y APIs de talla única
- Clientes charlatanes. El ejemplo de Newman es una lista de deseos: se obtiene la lista y luego los nombres, precios y niveles de stock de sus elementos. Son dos viajes de ida y vuelta dependientes; a, digamos, 150 ms cada uno en una red móvil, pasan 300 ms antes de que empiece el renderizado. Con un BFF el teléfono paga un solo viaje, y las llamadas dependientes se ejecutan dentro del centro de datos, donde un salto cuesta unos pocos milisegundos como mucho.
- Respuestas dimensionadas para la pantalla más grande. El teléfono descarga campos que nunca muestra.
- Un cuello de botella compartido. Cada equipo de cliente encola sus cambios para un único desplegable, a menudo en manos de otro equipo.
De qué es responsable un BFF
| Responsabilidad | En el BFF | No en el BFF |
|---|---|---|
| Agregación | Un endpoint por pantalla, que llama a los servicios en paralelo | Joins que todo cliente necesita; pertenecen a un servicio |
| Modelado de respuestas | Elegir, renombrar y formatear campos | Reglas de negocio como los precios |
| Autenticación y sesión | Cookie de sesión, almacenamiento y renovación de tokens | Autorización final; la deciden los servicios |
| Caché | Respuestas agregadas de corta duración | Datos personalizados en una caché indexada solo por URL |
| Feature flags | Qué variante ve este cliente | Flags que cambian el comportamiento del dominio |
BFF frente a API gateway frente a GraphQL
| API gateway | BFF | Servidor GraphQL | |
|---|---|---|---|
| Sirve a | Todos los clientes | Una experiencia de cliente | Cualquier cliente, mediante un esquema |
| Suele ser de | El equipo de plataforma | El equipo del cliente | Un equipo de graph, o los equipos de dominio mediante federación |
| Hace | TLS, enrutamiento, comprobación de tokens, límites de tasa | Agregación, modelado, sesión y tokens | Deja que los clientes elijan campos; los resolvers llaman a los servicios |
| Cambia cuando cambia una pantalla | No | Sí, en la misma release | A menudo solo cambia la consulta |
| Fallo típico | Se cuela lógica de negocio | Duplicación, fan-out lento | Consultas costosas, llamadas de resolvers N+1, caché HTTP más difícil |
Una configuración habitual pone un gateway en el borde con los BFF detrás, como en el diagrama de arquitectura de un API gateway. Un único graph compartido puede sustituir a los BFF por cliente, y la guía de patrones de Microsoft señala que, con resolvers específicos de cada frontend, los BFF separados pueden no aportar nada. El coste es el límite entre equipos: cada equipo de cliente negocia cambios sobre un único esquema.
Propiedad y límites entre equipos
El BFF pertenece al equipo del cliente: la aplicación web y su BFF cambian en una sola pull request y salen en una sola release. Newman señala que un equipo móvil puede incluso mover lógica a su BFF para publicar sin pasar por la revisión de una tienda de aplicaciones.
¿Cuántos BFF? Newman cita a Stewart Gleadow: una experiencia, un BFF. REA Group tenía BFF separados para iOS y Android; SoundCloud compartía uno entre sus aplicaciones de escucha para iOS y Android, y sus ingenieros le dijeron a Newman que podrían reconsiderarlo. La versión de Pete Hodgson es seguir los límites de los equipos. Tu organigrama de ingeniería debería mostrar exactamente un equipo responsable por cada BFF.
Un BFF de socio mantiene un contrato estable y versionado y lo asigna a los servicios a medida que cambian, de modo que el trabajo interno no rompa las integraciones de los socios. Enrutar a los socios directamente a APIs de servicio versionadas también funciona.
El BFF como gestor de tokens para aplicaciones de navegador
Una aplicación de una sola página que ejecuta OAuth por sí misma guarda los tokens en el navegador, donde cualquier script inyectado puede robarlos. La guía de JWT repasa dónde puede guardar los tokens una aplicación de navegador y el riesgo de cada opción. La RFC 10017, OAuth 2.0 for Browser-Based Applications, se convirtió en Best Current Practice (BCP 212) en agosto de 2026. Ordena tres arquitecturas de mayor a menor seguridad:
| Patrón | Dónde viven los tokens | Qué puede hacer el JavaScript inyectado | Veredicto de la RFC 10017 |
|---|---|---|---|
| BFF | Solo en el servidor | Enviar peticiones a través del BFF mientras la página esté abierta | Muy recomendado para aplicaciones empresariales y sensibles |
| Backend mediador de tokens | Token de acceso en el navegador, token de refresco en el servidor | Robar tokens de acceso y pedir otros nuevos al backend | Solo cuando un BFF completo no es viable |
| Cliente OAuth en el navegador | Todos los tokens en el navegador | Robar todos los tokens y ejecutar flujos nuevos | No recomendado para aplicaciones empresariales ni sensibles |
Aquí el BFF es un cliente OAuth confidencial. Ejecuta el flujo authorization code con PKCE, intercambia el código con sus propias credenciales, guarda los tokens asociados a la sesión del usuario y adjunta el token de acceso a cada llamada que reenvía. El navegador solo guarda una cookie; el diagrama del flujo OAuth 2.0 recorre el flujo de código.
Las reglas principales de la RFC:
- Cookie:
SecureyHttpOnlyson obligatorios; se recomiendanSameSite=Strict,Path=/, sinDomainy un prefijo en el nombre como__Host-Http-. Chrome y Firefox exigen ese prefijo; Safari, en el momento de escribir esto (noviembre de 2026), solo aplica su parte__Host-. - CSRF: es obligatoria una defensa. Una cabecera personalizada estática en cada llamada a la API fuerza un preflight de CORS en las peticiones entre orígenes.
- Proxy: reenvía solo a hosts de la lista de permitidos.
- Estado de sesión: un almacén del lado del servidor, que la RFC recomienda solo a pequeña escala, o tokens cifrados en la cookie, dentro de los 4 096 bytes por cookie que la RFC 6265 pide que admitan los navegadores. Haz que la sesión dure tanto como el token de refresco.
Set-Cookie: __Host-Http-sid=3f9c...; Secure; HttpOnly; SameSite=Strict; Path=/
// Same-origin fetch sends the cookie by default.
await fetch("/bff/orders", {
method: "POST",
headers: { "Content-Type": "application/json", "X-CSRF": "1" },
body: JSON.stringify(order),
});
Un BFF no detiene el cross-site scripting: el código inyectado todavía puede llamar al BFF mientras la página esté abierta, así que mantén una Content Security Policy. Las aplicaciones nativas siguen en cambio la RFC 8252 y ejecutan el flujo de código con PKCE en el navegador del sistema, por lo que un BFF móvil normalmente solo valida un token bearer.
Trampas
- Lógica duplicada. Newman prefiere algo de duplicación a código compartido que acople los BFF. Cuando una lógica aparece por tercera vez, extráela: una biblioteca para código técnico, un servicio de dominio para lógica de negocio. SoundCloud construyó un UserProfileService después de que unos cinco BFF ensamblaran cada uno perfiles de usuario.
- El BFF como monolito. Señales de alarma: es dueño de datos de dominio o reglas de negocio, otros BFF lo llaman o varios equipos hacen commits en él. Un descuento calculado por el BFF web pero no por el móvil es un bug que encontrará un cliente.
- Latencia de fan-out. Si un BFF llama a cinco servicios en paralelo, la probabilidad de que al menos uno responda más lento que su propio p99 es 1 − 0,99^5 ≈ 4,9 %: el p95 del BFF es aproximadamente el p99 de los servicios. The Tail at Scale, de Dean y Barroso, cubre las contramedidas.
- Un salto más. Cada BFF añade latencia, un despliegue y una rotación de guardias, y los servicios que limitan la tasa por dirección IP ahora solo ven la dirección del BFF.
Timeouts, respuestas parciales y circuit breakers
Fija un plazo por pantalla y repártelo: con 800 ms en el BFF, un timeout de 300 ms por llamada deja margen para un reintento. Ejecuta las llamadas independientes en paralelo y propaga el plazo.
Después decide qué datos son imprescindibles. La lista de deseos de Newman necesita la lista, pero puede renderizarse sin los niveles de stock. Devuelve lo que tengas y marca lo que falta:
{
"items": [{ "id": "sku-123", "name": "Trail shoe", "price": "$89.00" }],
"stock": null,
"errors": [{ "section": "stock", "reason": "timeout" }]
}
Da a cada servicio descendente su propio circuit breaker y su propio pool de conexiones, para que un servicio lento falle rápido en lugar de retener a cada worker; el patrón circuit breaker cubre umbrales y fallbacks. Reintenta solo lecturas idempotentes, en una sola capa, y no caches las respuestas agregadas más tiempo del que permite su parte más fresca.
El diagrama de arquitectura del BFF
Contenido del diagrama
- Shared services (domain teams)
- Identity provider
- Session store
- Web app
- Web BFF
- Mobile app
- Mobile BFF
- Partner system
- Partner BFF
- Catalog service
- Orders service
- Profile service
- session cookie only
- bearer access token
- client credentials token
- parallel calls + token
- parallel, fewer fields
- stable v1 mapping
- tokens by session ID
- 1. log in (redirect)
- 2. code + PKCE → tokens
Cómo leerlo:
- Una fila por experiencia de cliente, coloreada según el equipo responsable. Cada cliente llama solo a su propio BFF.
- Cada BFF se abre en abanico hacia los servicios compartidos; su flecha termina en el marco porque llama a los servicios que sus pantallas necesiten.
- Las aristas discontinuas son solo del inicio de sesión. El navegador se redirige al proveedor de identidad y luego el BFF web intercambia el código por tokens, el mismo paso que en un inicio de sesión con OpenID Connect.
- Los tokens se quedan en el servidor, en el almacén de sesiones bajo un ID de sesión. Una cookie cifrada también sirve, y la RFC 10017 la prefiere más allá de los despliegues pequeños.
- El bloque Markdown enumera los ajustes de la cookie y un ejemplo de presupuesto por pantalla.
Dibujar diagramas de BFF con claridad
- Da una fila a cada cliente con su BFF, etiquetada con el equipo responsable.
- Etiqueta lo que cruza cada arista: una cookie de sesión, un token bearer o credenciales de cliente.
- Muestra dónde viven los tokens, en un almacén o en una cookie cifrada.
- Dibuja el gateway aparte. Una sola caja para el gateway y los BFF oculta la propiedad.
- Cuidado con el hub. Una caja de BFF conectada a todos los clientes es un backend de propósito general.
- Omite la lista de endpoints. Basta una arista etiquetada por BFF hacia un límite de servicios; un diagrama de los microservicios detrás de los BFF cubre el lado de los servicios.
Constrúyelo en Archboard
- Inicia sesión con Google o GitHub y crea un diagrama.
- Del paquete Modelo C4, añade un Contenedor para la aplicación web y otro para la aplicación móvil, y un Sistema externo para el socio, uno por fila.
- Añade un Contenedor junto a cada cliente para su BFF, con una tecnología y una descripción.
- Añade un Marco del paquete Básico llamado Shared services (domain teams), que contenga tres nodos Contenedor: catalog, orders y profile.
- Encima de la fila web, añade un Proveedor de identidad del paquete Seguridad y un nodo Redis del paquete Datos como almacén de sesiones.
- Conecta cada cliente con su BFF y cada BFF con el marco, etiqueta las aristas, haz discontinuas las dos aristas de inicio de sesión y colorea cada fila por equipo.
- Añade un bloque Markdown de Básico con los ajustes de la cookie y el presupuesto, y etiquetas Texto de Básico para los equipos.
Si tus servicios ya están en un flowchart de Mermaid, el conversor de Mermaid te da un primer borrador editable. El ejemplo usa 13 nodos de diagrama, dentro del plan Free.
Preguntas frecuentes
¿Qué es el patrón backend for frontend (BFF)? Una API del lado del servidor construida para una experiencia de cliente, como una aplicación web, una aplicación móvil o una integración de socio, y a cargo del equipo de ese cliente. Agrega llamadas al backend y da forma a las respuestas.
¿Cuál es la diferencia entre un BFF y un API gateway? Un gateway sirve a todos los clientes y se ocupa del enrutamiento, la comprobación de tokens y los límites de tasa. Un BFF sirve a un cliente y cambia con sus pantallas. Muchos sistemas ponen un gateway delante de varios BFF.
¿GraphQL sustituye al patrón BFF? Puede, porque los clientes eligen los campos que necesitan. Aun así, alguien debe ser dueño del esquema y de los límites de las consultas, y un servidor GraphQL construido para un solo cliente es en sí mismo un BFF.
¿Cómo funciona la autenticación con un BFF? El BFF es un cliente OAuth confidencial: ejecuta el flujo authorization code con PKCE, guarda los tokens en el servidor y da al navegador solo una cookie de sesión HttpOnly.
¿Cuántos BFF debería tener? Uno por experiencia de usuario, alineado con tus equipos. Dos aplicaciones con la misma experiencia y el mismo equipo responsable pueden compartir uno.