Gino Kaleb gino kaleb SYS ADMIN
/

Un backend simulado en el navegador

Para no frenar el frontend, repliqué la lógica del backend en JavaScript y usé localStorage como base de datos. Así pude probar el sistema completo sin un solo servidor.

Todo empezó con un plan clásico. Estaba diseñando el “Proyecto Fénix”, un sistema para gestionar solicitudes académicas: un backend en Spring Boot que manejaría la lógica de negocio, la seguridad y la persistencia de datos, y un frontend en JavaScript puro para consumir la API.

Sobre el papel funcionaba. En la práctica se convirtió en un cuello de botella.

El problema: esperar al backend

El núcleo del sistema era un motor de reglas de negocio bastante complejo. Una solicitud no era simplemente “aprobada” o “rechazada”: pasaba por una cascada de validaciones. ¿El periodo de solicitud está activo? ¿El usuario ya tiene solicitudes en proceso? ¿Su estatus académico lo permite? ¿Tiene bloqueos administrativos? Cada motivo (conflicto de horario, situación laboral, problema de salud) disparaba un árbol de decisiones distinto, que además dependía del semestre del usuario, su promedio y otros factores.

Mi trabajo en el frontend se interrumpía a cada rato. Implementaba un formulario, pero necesitaba el endpoint de elegibilidad para habilitar el botón de envío. Diseñaba la vista de “mis solicitudes”, pero la estructura de datos final todavía se estaba discutiendo en el backend. Cada ajuste en las reglas significaba esperar a que el backend se actualizara, se desplegara y estuviera disponible. No era culpa de nadie: así se comporta un sistema acoplado en sus primeras fases. Pero el avance era lento.

En medio de esa lentitud me hice una pregunta: ¿y si en lugar de simular respuestas de la API simulara el backend completo?

Replicar el motor en el navegador

La idea iba más allá de devolver un JSON estático. Decidí portar la lógica de negocio completa (el ElegibilidadService y el EvaluacionSolicitudService que vivían en Java) a un archivo JavaScript, para tener una réplica funcional del motor de decisiones corriendo enteramente en el navegador.

Primero definí un contrato de API claro y lo fijé como el pacto entre el front y el back. Luego vino la réplica:

  • Una base de datos en el navegador: usé localStorage como base de datos efímera. Cada solicitud “enviada” en el prototipo se guardaba ahí, con persistencia entre sesiones, simulando un historial real.
  • El motor de reglas en JavaScript: traduje cada if, else if y switch de Java a funciones de JavaScript. La misma lógica determinista que decidía el destino de una solicitud, ahora en el cliente.
  • Una API estática: creé un objeto global, una especie de StaticAPI, con métodos llamados igual que los endpoints REST: solicitar(), consultar(), cancelar(). El resto del frontend usaba ese objeto sin saber que no había un fetch real detrás. Ese detalle fue clave: el día que el backend real estuviera listo, bastaría reemplazar StaticAPI por el cliente HTTP, sin tocar la lógica de la interfaz.

El resultado fue un mock que no se sentía como mock: un entorno de desarrollo autocontenido.

Lo que gané además de velocidad

Lo primero fue lo obvio: el desarrollo se aceleró. Podía construir y probar flujos de usuario completos sin dependencias externas, y pulir la interfaz sobre respuestas instantáneas y coherentes.

Lo segundo me sorprendió más: las pruebas de usuario mejoraron. En lugar de enseñar maquetas estáticas o prototipos que solo seguían el camino feliz, entregaba una aplicación funcional. La gente probaba casos límite, exploraba escenarios distintos, y su feedback era sobre la experiencia real. Así aparecieron fallos y ambigüedades en las propias reglas de negocio mucho antes de escribir la versión final en el backend.

Y lo tercero: un desacoplamiento de verdad. El backend podía concentrarse en seguridad, escalabilidad y optimización, con la tranquilidad de que el contrato de la API era la única zona de contacto. El mock funcionaba como documentación viva del comportamiento esperado.

Cuando llegó el momento de integrar el backend real, el proceso fue casi aburrido: reemplacé el proveedor de datos estático por el cliente HTTP y todo funcionó a la primera. Sin sorpresas ni reajustes de última hora. El trabajo duro ya estaba hecho.