TFG — Javier Mengual — 2026
Tu frontend merece algo mejor que strings rotos
Dolibarr funciona. Pero su API devuelve un desastre que no puedes entregarle a un frontend moderno y decir "aquí tienes, apañatelas".
Lo que te da Dolibarr
"string""1"Lo que tu frontend merece
int"unpaid"El patrón BFF —Backend for Frontend— no es un proxy. Es una capa que traduce, protege y enriquece. Tu frontend habla con él, y él se ocupa de lo demás.
Si voy a poner una API en producción, quiero dormir tranquilo tres años.
LTS hasta 2028
Tres años de soporte. Me da igual lo que pase meantime.
Rendimiento
Lo suficientemente rápido para que la latencia no sea un problema.
Todo incluido
JWT, rate limiting, health checks, OpenAPI. Sin buscar librerías raras.
Auth — login, JWT
Facturas — CRUD, líneas, pagos, estado
Clientes — con contactos incluidos
Proveedor — facturas de proveedor
Bancos — cuentas y movimientos
Documentos — PDFs de facturas
Setup — diccionarios, país, compañía
Notificaciones — webhooks
Sí, gran parte es 1:1 con Dolibarr. Pero el BFF añade lo que el ERP no tiene: tipos correctos, estados legibles, enriquecimiento con nombres de cliente y notificaciones.
Dolibarr
{
"statut": "1",
"total_ttc": "150.50",
"date": "1715673600",
"socid": "3"
}
BFF
{
"status": "unpaid",
"total": 150.50,
"date": "2024-05-14",
"clientId": 3
}
Mismo dato. Otro mundo.
OpenAPI 3.1 generado al arrancar. Cada endpoint documentado.
El frontend maneja un JWT. La API key de Dolibarr queda atrapada dentro del BFF. Si alguien intercepta el token del usuario, caduca en 8 horas y no tiene acceso al ERP.
1 — Login
El usuario se autentica. El BFF recibe la API key de Dolibarr y la guarda en memoria.
2 — JWT
El BFF genera un JWT para el navegador. La API key nunca sale de ahí.
3 — Cada petición
El JWT lleva un sessionId. Con ese sessionId se busca la API key en caché y se inyecta al vuelo.
Cada usuario tiene su propia API key aislada. Si se cachease en el HttpClient, todos compartirían la misma.
Al poner una capa por delante, puedes añadirle cosas que Dolibarr nunca va a tener. El ejemplo más claro: cuando una factura cambia de estado, el equipo se entera al momento. Sin abrir el sistema, sin mirar nada.
Teams, Slack, lo que sea
Configuras una URL y avisa donde quieras. Hoy es Teams, mañana puede ser Telegram, email, lo que haga falta.
La interfaz ya está
Añadir un canal nuevo es implementar una interfaz. El resto del código ni se toca. Así se escala un wrapper de verdad.
docker compose up
services:
mysql:
image: mysql:8.0
environment:
MYSQL_DATABASE: dolibarr
volumes: [mysql_data:/var/lib/mysql]
dolibarr:
image: dolibarr/dolibarr:latest
depends_on: [mysql]
ports: ["80:80"]
bff:
build: ./DoliMiddlewareApi
depends_on: [dolibarr]
ports: ["5001:8080"]
MySQL, Dolibarr, el BFF. Tres contenedores, un comando.