Cuando pensamos en construir una interfaz para diseñar y lanzar flujos de trabajo —especialmente si esos flujos acaban ejecutándose en un sistema como Argo Workflows—, necesitamos algo más que una buena librería de frontend: necesitamos una plataforma que nos permita integrar lógica del lado del servidor, gestionar peticiones a APIs, renderizar vistas dinámicas y mantener todo bien organizado.
Ahí es donde Next.js se convierte en una opción muy interesante. No solo por ser una de las tecnologías más populares del ecosistema React, sino porque cubre una amplia gama de necesidades comunes en este tipo de aplicaciones, tanto del lado cliente como del servidor.
En este post vamos a explorar por qué Next.js puede ser una buena base para desarrollar una interfaz visual orientada a flujos de trabajo, y cómo se puede conectar de forma práctica con Argo Workflows.
¿Por qué usar Next.js para una interfaz de flujos?
Next.js ofrece un enfoque híbrido que permite combinar distintas formas de renderizado: generación estática, renderizado del lado del servidor (SSR), React Server Components, y funciones serverless integradas. Esta flexibilidad lo hace ideal para aplicaciones que necesitan mostrar interfaces dinámicas (por ejemplo, un canvas visual de un DAG) junto con lógica de backend para comunicarse con sistemas externos como Argo.
Estas son algunas de las razones por las que Next.js encaja bien en este tipo de proyecto:
Necesidad | ¿Cómo lo resuelve Next.js? |
---|---|
Interfaces dinámicas y visuales | Total compatibilidad con librerías como React Flow, D3, visx… |
Comunicación con APIs externas | Route Handlers y Server Actions permiten hacer llamadas a Argo directamente desde el servidor |
Control total del renderizado | Podemos elegir entre pre-render, SSR o RSC según el tipo de página o componente |
Facilidad de despliegue | Puede ejecutarse en Vercel, Docker o en cualquier entorno Node o Edge |
Proyecto unificado | Frontend y backend conviven en el mismo repo, facilitando el desarrollo |
¿Cómo se conecta esto con Argo Workflows?
Argo Workflows expone una API REST (y también GRPC) desde su componente argo-server
. Desde Next.js, podemos interactuar con esa API de varias formas. La más recomendable suele ser a través de un Route Handler (lo que antes eran las API Routes), que actúe como intermediario entre el cliente y Argo.
Por ejemplo, podríamos tener algo así:
// app/api/argo/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function POST(req: NextRequest) {
const body = await req.json();
const res = await fetch('https://argo.example.com/api/v1/workflows/my-ns', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
return NextResponse.json(await res.json(), { status: res.status });
}
Este enfoque tiene varias ventajas:
- Podemos añadir autenticación, validación y logs desde un único lugar.
- Evitamos exponer directamente el endpoint de Argo en el navegador.
- Mantenemos la lógica de negocio cerca del frontend, sin necesidad de levantar un backend aparte.
También existe la opción de hacer peticiones directamente desde el cliente, pero eso suele ser menos seguro y más difícil de escalar si Argo está protegido por firewalls o requiere autenticación especial.
¿Cómo sería el flujo completo: de la UI visual al manifiesto de Argo?
Una aplicación de este tipo suele tener un editor visual (por ejemplo, con React Flow) donde el usuario dibuja nodos y conexiones. Esa información se puede transformar automáticamente en un manifiesto YAML que Argo entienda.
Un posible flujo sería:
- El usuario crea un DAG en el canvas visual.
Guardamos nodos y conexiones en el estado de React. - Cuando pulsa «Generar YAML», enviamos el grafo al servidor.
Podemos usar una Server Action o un API Route. - En el servidor, convertimos ese grafo a YAML.
Usamos una función que traduce nodos y edges a un DAG válido para Argo. - Devolvemos el YAML al cliente, o lo enviamos directamente al API de Argo.
Esta arquitectura es muy flexible y permite mantener toda la lógica en el mismo proyecto. Además, si queremos extender la app más adelante (por ejemplo, para incluir logs, métricas o un historial de ejecuciones), ya tenemos las herramientas necesarias dentro de Next.js para hacerlo.
Ventajas claras de usar Next.js en este contexto
- Desarrollo rápido: puedes tener una demo funcional en muy poco tiempo usando
create-next-app
, React Flow y un par de handlers. - Integración nativa con backend: puedes construir y lanzar flujos sin necesidad de configurar un servidor aparte.
- Escalabilidad y despliegue sencillo: funciona bien tanto en entornos cloud como en on-premise.
- Observabilidad: puedes añadir fácilmente herramientas de logging, métricas o tracing usando middlewares o librerías como OpenTelemetry.
Algunos retos y cómo abordarlos
Como todo, no todo son ventajas. Algunos puntos a tener en cuenta:
Desafío | Posible solución |
---|---|
Gestión de estados complejos en tiempo real (como los eventos de watch de Argo) | Usar un servicio de WebSockets externo y retransmitir eventos por Server-Sent Events (SSE) o APIs internas |
Tamaño del bundle | Cargar librerías pesadas (como editores visuales) mediante dynamic import() para reducir el impacto |
Procesos largos (como generación de YAML complejos) | Mover esa lógica a un microservicio o job que pueda ejecutarse de forma asincrónica |
¿Cuándo tiene sentido usar Next.js para esto?
Situación | ¿Encaja Next.js? |
---|---|
Quieres una interfaz visual moderna, con integración backend incluida | ✅ |
Ya trabajas con React y TypeScript | ✅ |
Necesitas soporte SSR, RSC o render mixto | ✅ |
Tu aplicación es puramente cliente y no necesita backend | ❌ Puede que Vite sea más ligero |
El backend requiere ejecución prolongada o flujos en tiempo real intensivos | ⚠️ Mejor separar responsabilidades con servicios externos |
Conclusión
Next.js no es una herramienta pensada específicamente para la orquestación de flujos, pero gracias a su flexibilidad, puede ser una gran base para construir interfaces visuales que se conecten con sistemas como Argo Workflows.
Permite cubrir toda la cadena: desde la edición del flujo por parte del usuario, hasta su traducción a YAML y su envío al sistema de orquestación. Y lo hace sin necesidad de levantar múltiples servicios, ni mantener un frontend separado de un backend.