Next.js
Next.js como Backend for Frontend
Explica cuándo Next.js funciona como Backend for Frontend, agregando servicios, sesiones, DTOs, Actions y APIs sin reemplazar dominios o jobs especializados.
- Última actualización
- Actualizada
- Nivel
- Aplicación
Next.js
Explica cuándo Next.js funciona como Backend for Frontend, agregando servicios, sesiones, DTOs, Actions y APIs sin reemplazar dominios o jobs especializados.
Como Backend for Frontend, Next.js actúa como una capa servidor diseñada para las necesidades de una interfaz concreta: mantiene sesión, agrega servicios, transforma DTOs, renderiza Server Components y expone Actions o Route Handlers. No pretende reemplazar automáticamente cualquier backend, worker, sistema de eventos o servicio de dominio.
browser
→ Next.js BFF
├─ session/auth
├─ UI-specific aggregation
├─ Server Components
├─ Server Actions
└─ Route Handlers
→ domain services / database / providersEl BFF adapta capacidades a una experiencia. La lógica crítica puede vivir dentro del mismo deployment si ese es su contexto real.
Sin BFF, el navegador puede:
Con BFF:
one UI request
→ authorize once
→ fetch several sources in server
→ map minimal view model
→ stream/render resultPara una lectura usada solo por la UI Next.js, accede al servicio interno directamente:
export default async function DashboardPage() {
const dashboard = await getDashboardForCurrentUser();
return <DashboardView dashboard={dashboard} />;
}No hagas fetch("http://localhost/api/dashboard") hacia tu propio Route Handler. Añade red, serialización y otra auth sin consumidor externo.
Adecuadas para mutaciones iniciadas por UI React:
form intent
→ Action validates/authenticates
→ service transaction
→ invalidation
→ UI state/redirectNo son una API pública universal. Un móvil o webhook necesita HTTP/otro contrato.
Úsalos para:
No crees un endpoint por cada función servidor si nadie necesita HTTP.
const [profile, plan, notifications] = await Promise.all([
profileService.get(userId),
billingService.getPlan(userId),
notificationService.listUnread(userId),
]);
return toDashboardView({ profile, plan, notifications });Define timeouts y degradación por dependencia. Si notificaciones son opcionales, no deben bloquear perfil y plan.
El BFF devuelve:
type DashboardView = {
greeting: string;
planLabel: string;
unreadCount: number;
actions: Array<{ key: string; enabled: boolean }>;
};No expone entidades completas de tres servicios. Sin embargo, no coloques copy/markup específico dentro del dominio central si otros consumidores lo necesitan.
El BFF es buen lugar para convertir cookie de sesión en principal interno. No reenvíes la cookie del usuario a servicios arbitrarios. Usa credenciales service-to-service con scopes y propaga actor/tenant de forma firmada/controlada cuando el downstream deba autorizar.
Aunque Next.js autentique, el servicio/DAL que ejecuta la acción vuelve a comprobar permisos. Un downstream independiente no debe confiar únicamente en que “vino del frontend”.
Agregados públicos pueden cachearse. Datos personales suelen ser dinámicos o requieren key privada segura. Si una respuesta mezcla público y privado, separa componentes:
cached catalog
+ dynamic account summaryNo caches el dashboard entero globalmente por comodidad.
Mapea errores internos a resultados de UI o HTTP sin revelar topología:
billing timeout
→ plan temporarily unavailable
→ warning + retryPara checkout, billing puede ser crítico y la operación falla. El BFF decide presentación, no inventa éxito.
Trace:
Next.js request
├─ auth
├─ profile service
├─ billing service
└─ notification serviceRegistra latencia por dependencia, outcome y request ID. Sin esto, una agregación lenta parece “Next.js lento”.
Un monolito Next.js modular puede ser más simple y confiable que separar prematuramente.
Separar no significa que el navegador deba llamar directo: Next.js puede seguir siendo BFF frente al servicio.
Una Action no debe mantener la request abierta durante minutos:
Action validates
→ create job record/outbox
→ enqueue
→ return job ID
→ UI polls/subscribesEl worker tiene retries, idempotencia y dead-letter.
Next.js no puede hacer una transacción ACID entre DB, payment y email. Usa:
No encadenes servicios suponiendo rollback automático.
Un endpoint interno solo para una app desplegada junto puede evolucionar coordinadamente. Una API pública/móvil necesita versionado y compatibilidad más estrictos.
Define contratos OpenAPI/GraphQL cuando aporten a múltiples consumidores, no para una función local.
El BFF no debe convertirse en proxy abierto.
customer/admin/delivery UIs
→ Next.js BFF per web experience
→ shared domain services
→ PostgreSQL + external providersSi las tres interfaces viven juntas, módulos internos pueden servir. Si móvil/partners consumen pedidos, extrae un contrato de API estable sin duplicar reglas.
HTTP interno innecesario.
Reglas divergen del servicio.
Expone tokens/topología.
Timeout y mala recuperación.
Filtra cookies/internos.
Cada endpoint accede a todo.
Coste operativo sin necesidad.
Integración con PostgreSQL y ORM concreta persistencia, pooling, transacciones y migraciones.