Desarrollo backend en Java: APIs, datos e integraciones
Las decisiones de diseño de una API y de su modelo de datos condicionan el sistema durante años, porque son las más difíciles de cambiar una vez hay consumidores.
Un backend se juzga por cómo se comporta cuando algo va mal
No por cómo funciona en el camino feliz: devolver errores comprensibles, no perder datos ante un reintento y degradar de forma controlada.
Esas propiedades dependen de decisiones que se toman al principio y que resultan caras de introducir después: el contrato de la API, el modelo de datos, dónde están los límites transaccionales y qué se registra en cada operación.
Lo que casi nunca marca la diferencia es la elección entre frameworks equivalentes. Un backend bien diseñado en Spring Boot y otro en Quarkus se parecen mucho más entre sí que dos backends con el mismo framework y distinta disciplina de diseño.
Diseño y versionado de la API
Se diseña a partir de los recursos del dominio y de los casos de uso reales del consumidor, no exponiendo el modelo de base de datos.
Exponer entidades JPA directamente como respuesta es el atajo más caro del desarrollo backend: acopla el contrato público al esquema, provoca serializaciones accidentales de relaciones perezosas y convierte cualquier cambio de columna en un cambio incompatible para todos los consumidores.
DTO explícitos
De entrada y de salida, distintos de las entidades de persistencia y con su propio ciclo de vida.
Versión desde el día uno
En la ruta (/v1/…) desde la primera publicación, aunque solo exista un consumidor.
Cambios aditivos
Añadir campos es compatible; quitarlos o renombrarlos rompe a quien ya consume la API.
Errores uniformes
Estructura constante —código, mensaje y detalle— y códigos HTTP correctos.
Contrato generado
OpenAPI generado desde el código, para que la documentación no se desactualice.
Distinguir el error de negocio del fallo técnico
Ambos se traducen a respuestas coherentes en un único punto, no en cada controlador.
Un error de negocio —saldo insuficiente, referencia inexistente— es una respuesta válida del sistema y debe devolver un código específico que el cliente pueda tratar. Un fallo técnico —base de datos inaccesible, timeout— es un 5xx que debe registrarse con contexto suficiente para diagnosticarlo.
Dos prácticas que cambian mucho la operación: incluir en toda respuesta de error un identificador de correlación que el usuario pueda facilitar en un incidente, y no exponer nunca trazas de excepción ni detalles internos en la respuesta, porque son información útil para un atacante y ruido para un cliente legítimo.
Los límites transaccionales van en el caso de uso
No en el repositorio ni en el controlador. Una transacción debe abarcar exactamente la operación de negocio que tiene que ser atómica, y nada más.
Los dos errores habituales son simétricos: transacciones demasiado amplias, que mantienen abierta una conexión mientras se hace una llamada HTTP externa y agotan el pool en cuanto el servicio remoto se ralentiza; y transacciones demasiado estrechas, que dejan la operación a medias si falla el segundo paso.
Una regla operativa fiable: dentro de una transacción no debe haber ninguna llamada de red que no sea a la propia base de datos. Todo lo demás —notificaciones, publicación de eventos, llamadas a terceros— va fuera, y si debe ser atómico con el cambio de datos se resuelve con el patrón outbox.
Transversal, no dependiente de que cada desarrollador se acuerde
El mínimo que reviso en cualquier auditoría de un backend Java.
Autorización en servidor
Comprobada sobre cada operación, nunca confiando en que la interfaz oculte una opción.
Validación en el límite
Declarativa y aplicada antes de que el dato entre en el dominio.
Consultas parametrizadas
Siempre. Ninguna concatenación de cadenas para construir SQL o JPQL.
Secretos externos
En un gestor dedicado, nunca en el repositorio ni en ficheros de propiedades versionados.
Dependencias analizadas
Con análisis automático de vulnerabilidades en el pipeline: la mayoría de los incidentes llegan por ahí.
Preguntas frecuentes
Dudas habituales sobre backend java en proyectos empresariales.
¿Qué hace sólido a un backend Java?
Un backend Java sólido se reconoce por cómo se comporta cuando algo va mal: devuelve errores comprensibles, no pierde datos ante un reintento, degrada de forma controlada cuando una dependencia falla y permite entender qué ha ocurrido sin reproducirlo. Esas propiedades dependen del contrato de la API, del modelo de datos, de dónde están los límites transaccionales y de qué se registra en cada operación.
¿Cómo se diseña y se versiona una API REST en Java?
Se diseña a partir de los recursos del dominio y de los casos de uso reales del consumidor, no exponiendo el modelo de base de datos, y se versiona desde la primera publicación. Conviene usar DTO explícitos distintos de las entidades de persistencia, versión en la ruta, cambios aditivos siempre que sea posible, errores con estructura uniforme y contrato documentado con OpenAPI generado desde el código.
¿Cómo se gestionan los errores en un backend Java?
Distinguiendo entre errores de negocio esperados y fallos técnicos, y traduciéndolos a respuestas coherentes en un único punto en lugar de en cada controlador. Un error de negocio devuelve un código específico que el cliente puede tratar; un fallo técnico es un 5xx que se registra con contexto. Conviene incluir un identificador de correlación en cada respuesta de error y no exponer nunca trazas de excepción.
¿Dónde deben estar los límites transaccionales?
En el caso de uso, no en el repositorio ni en el controlador: la transacción debe abarcar exactamente la operación de negocio que tiene que ser atómica. Una regla fiable es que dentro de una transacción no haya ninguna llamada de red que no sea a la propia base de datos; las notificaciones, la publicación de eventos y las llamadas a terceros van fuera, y si deben ser atómicas se resuelven con el patrón outbox.
¿Qué aspectos de seguridad no pueden faltar en un backend Java?
Autorización comprobada en el servidor sobre cada operación, validación de entrada declarativa aplicada en el límite del sistema, consultas siempre parametrizadas, secretos en un gestor externo fuera del repositorio y análisis automático de vulnerabilidades de las dependencias en el pipeline, ya que la mayoría de los incidentes llegan por esa vía.
Recursos relacionados
Páginas pilar, guías y casos reales que amplían lo tratado aquí.
- Spring Boot El framework y sus errores más frecuentes.
- Arquitectura Hexagonal Cómo estructurar el backend por dentro.
- Java Microservicios Cuando el backend se reparte en servicios.
- Java Performance Diagnóstico de latencias y pools.
- Java Freelance Incorporar un perfil senior al equipo.
- Auditoría técnica Revisión de código y arquitectura existentes.
¿Necesitas reforzar tu backend Java?
Reviso el diseño de la API, el modelo de datos y la gestión de errores, y acompaño al equipo en la corrección de lo que más riesgo genera.