C4 como Código: Arquitectura Viva con Java, Quarkus y GitLab
1. Introducción: El fin de la era de la documentación "muerta"
En el desarrollo de software moderno, la documentación arquitectónica suele sufrir un destino trágico: nace con entusiasmo en herramientas de "cajas y líneas" (como Visio o archivos binarios propietarios) y muere lentamente a medida que el código evoluciona. Un diagrama estático es, en el mejor de los casos, una "polaroid" de un sistema que ya no existe. Para un Arquitecto Senior, estas representaciones opacas son deudas técnicas disfrazadas de claridad.
La solución no es dejar de documentar, sino adoptar el paradigma Docs-as-Code. Al utilizar el modelo C4 como código, transformamos la arquitectura en una "transmisión en vivo" integrada en el flujo de trabajo de ingeniería. Al igual que el código de nuestras aplicaciones Quarkus, la arquitectura debe vivir en archivos de texto, bajo control de versiones en GitLab, sujeta a code reviews mediante Merge Requests y validada automáticamente en pipelines de CI/CD.
2. Fundamentos del Modelo C4: Abstracción con Propósito
El modelo C4 no es una notación rígida, sino una jerarquía de "zoom controlado" diseñada para diferentes audiencias. Su valor reside en separar el ruido del diseño según el nivel de detalle requerido.
- Nivel 1: Contexto del Sistema (System Context): La "gran imagen". Muestra el sistema en su totalidad, los usuarios y las dependencias externas (ej. Core Banking). Es el nivel que entiende tanto el negocio como el equipo técnico.
- Nivel 2: Contenedores (Containers): Define las fronteras de despliegue o ejecución. En nuestro ecosistema, un contenedor no es solo Docker; es una API de Quarkus, un esquema de base de datos PostgreSQL, un consumidor de eventos o un batch job.
- Nivel 3: Componentes (Components): Zoom dentro de un contenedor para identificar bloques lógicos (API Adapters, Application Services, Repositorios). Ayuda a entender la estructura interna sin ahogarse en las clases de Java.
- Nivel 4: Código (Code): Opcional. Reservado para diagramas de clases UML o ERDs de partes críticas que requieren precisión técnica extrema.
3. El Paradigma de "C4 como Código" y Structurizr DSL
La transición fundamental es pasar de "dibujar" a "modelar". Las herramientas genéricas operan con formas visuales; el enfoque Model-first de Structurizr DSL construye una base de datos de elementos y relaciones, y luego proyecta vistas sobre ella. Si renombras un servicio en el modelo, se actualiza en todos los diagramas automáticamente.
Structurizr DSL es la recomendación canónica para entornos Java/Quarkus por su legibilidad y capacidad de realizar diffs reales en Git. A continuación, un ejemplo de un servicio de pagos:
workspace "Payments" "Payments service architecture" {
!identifiers hierarchical
model {
user = person "Bank Customer"
coreBanking = softwareSystem "Core Banking"
payments = softwareSystem "Payments Service" {
api = container "Payments API" "REST API for payment initiation" "Java, Quarkus"
db = container "Payments DB" "Stores payment state" "PostgreSQL"
api -> db "Reads and writes"
}
user -> payments.api "Initiates payments"
payments.api -> coreBanking "Validates accounts and posts transactions"
}
views {
systemContext payments "context" {
include *
autoLayout lr
}
container payments "containers" {
include *
autoLayout lr
}
# El uso de 'keys' explícitas es vital para la persistencia del layout
styles {
element "Container" {
background #1168bd
color #ffffff
}
}
}
}
4. Batalla de Herramientas: ¿Por qué Structurizr es el Rey en Java/Quarkus?
No todas las herramientas de "texto a diagrama" son iguales. La siguiente comparativa técnica destaca por qué Structurizr es la fuente de verdad preferida.
| Herramienta | Enfoque | Curva de Aprendizaje | Ajuste con GitLab/Java | Recomendación |
|---|---|---|---|---|
| Structurizr DSL | Modelo primero | Moderada | Excelente. Nativo de Java. Soporta exportación a otros formatos. | Principal. Evita el lock-in y asegura consistencia. |
| PlantUML (C4-PlantUML) | Diagrama primero | Baja | Buena. Muy común, pero cada diagrama es independiente. | Secundaria. Útil para validaciones con ArchUnit. |
| Mermaid C4 | Diagrama primero | Muy baja | Excelente ergonomía nativa en GitLab. | Limitada. Experimental e inestable. Carece de leyendas y tags. |
5. Estrategia de Entrega en GitLab: El Pipeline de Arquitectura
Para que la arquitectura sea "viva", el pipeline debe automatizar su integridad. El flujo recomendado es: Autoría (DSL) -> Validación/Inspección (CI) -> Publicación (GitLab Pages).
Consideraciones Técnicas Críticas:
- Stable View Keys: Es imperativo asignar keys estables a las vistas en el DSL. Sin ellas, los identificadores generados por la herramienta cambiarán aleatoriamente, rompiendo cualquier layout manual que hayamos curado en el archivo workspace.json.
- Limitación de ADRs: Advertencia importante: el comando de exportación a sitio estático de Structurizr elimina la documentación narrativa y los ADRs (Architecture Decision Records). Para un portal de arquitectura completo en GitLab Pages, recomiendo usar un generador de sitios estáticos (como MkDocs o Antora) e incrustar los diagramas exportados.
Configuración del Pipeline (.gitlab-ci.yml):
El pipeline debe incluir el comando inspect para verificar la calidad del modelo (metadatos faltantes, descripciones vacías) junto con validate.
6. Ingeniería Directa e Inversa: Realismo frente a Automatización
La colaboración efectiva requiere una división clara: los arquitectos establecen el contexto y contenedores (C1/C2), mientras que los desarrolladores mantienen los componentes (C3) en sus propios repositorios.
Sin embargo, debemos ser realistas: la ingeniería inversa total es un mito. Herramientas como structurizr-component para Java pueden descubrir componentes basados en convenciones de paquetes de Quarkus, pero este proceso debe ser un complemento, no un sustituto del modelado manual. La automatización funciona solo si el código es disciplinado.
Gobernanza con ArchUnit: Para evitar la erosión de lo que hemos diseñado, utilizamos ArchUnit. Específicamente, la funcionalidad FreezingArchRule es fundamental en proyectos brownfield para registrar violaciones actuales y evitar que la deuda técnica crezca mientras migramos hacia el modelo C4 ideal.
7. Playbook de Migración: De Sparx EA a la Agilidad del DSL
Migrar desde herramientas legadas como Sparx EA no es una conversión mecánica de XML; es una traducción de conocimiento.
- Clasificar: Evaluar artefactos para Retener (archivo histórico), Traducir (re-escribir en C4 DSL) o Retirar (eliminar si nadie los consume).
- Establecer el Catálogo del Sistema: Antes de modelar servicios individuales, cree un catálogo centralizado de Personas y Sistemas externos. Esto evita que cada equipo defina "Core Banking" de forma distinta, permitiendo una visión de "Landscape" coherente en toda la organización.
- Migración Híbrida: En sistemas existentes, modele manualmente C1 y C2. Use ingeniería inversa selectiva para C3 solo donde aporte valor real al diseño.
8. Conclusión: Hacia una Documentación que Evoluciona con el Código
Adoptar C4 como código transforma la documentación de ser una carga administrativa a un activo estratégico. Al centralizar la arquitectura en GitLab, permitimos que las revisiones de diseño ocurran en el mismo lugar donde se escribe el código: los Merge Requests.
La mejor documentación es la que reside donde los desarrolladores trabajan. Inicie hoy mismo un piloto con un solo microservicio Quarkus, mueva sus diagramas al repositorio y deje que su arquitectura vuelva a la vida. Es hora de dejar de dibujar y empezar a modelar.


Comentarios
Publicar un comentario