Socle Java/Spring Boot extrait de 5 mois de production réelle. 658 commits. Pas un tutoriel, une base de travail éprouvée.
K comme Kouba. ORE comme core, le socle.
Ce n'est pas un acronyme inventé après coup. Le nom est venu naturellement : mon identité derrière, la philosophie devant. Construire des fondations solides avant de construire des fonctionnalités. Penser architecture avant code.
KORE est un projet open source destiné à la communauté.
C'est aussi la première brique d'un écosystème plus large. kore-batch, kore-stream, kore-react sont prévus. Chaque brique suivra la même logique : extraite de production, documentée, testée, utile.
J'ai conçu et mis en production une plateforme SaaS from scratch. Chaque décision d'architecture a été prise sous contrainte réelle : données en production, utilisateurs actifs, CI/CD qui devait tenir, vélocité qui ne pouvait pas s'effondrer.
Au fil des 658 commits, certains patterns ont prouvé leur valeur. D'autres ont échoué et ont été remplacés. KORE est ce qui reste : le socle épuré, documenté, prêt à être réutilisé sur n'importe quel projet.
Ce dépôt sert à la fois de référence technique et de point de départ pour tout projet Java qui vise la maintenabilité à long terme.
| Couche | Technologie |
|---|---|
| Langage | Java 21 |
| Framework | Spring Boot 3.2 |
| Architecture | Hexagonale (Ports & Adapters) + CQRS |
| Messagerie | Apache Kafka |
| Base de données | PostgreSQL |
| Sécurité | Spring Security + JWT |
| Observabilité | Prometheus + Grafana |
| Couche | Technologie |
|---|---|
| Framework | React 19 |
| Build | Vite |
| Style | Tailwind CSS |
| Domaine | Technologie |
|---|---|
| Conteneurisation | Docker / Docker Compose |
| CI/CD | GitHub Actions |
Séparation stricte entre logique métier et infrastructure via le pattern Ports & Adapters.
┌─────────────────────────────────────────────────────────┐
│ Côté Pilotant │
│ (Contrôleurs REST, Consumers Kafka) │
└──────────────────────┬──────────────────────────────────┘
│ Ports Pilotants
▼
┌─────────────────────────────────────────────────────────┐
│ Noyau Applicatif │
│ │
│ Commandes --> Handlers --> Modèle de Domaine │
│ Requêtes --> Handlers │
│ │ │
│ Ports Pilotés │
└──────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Côté Piloté │
│ (Repositories JPA, Producers Kafka, │
│ Adaptateurs HTTP externes) │
└─────────────────────────────────────────────────────────┘
CQRS : les commandes mutent l'état et émettent des événements de domaine via Kafka ; les requêtes retournent des projections depuis le modèle de lecture. Le domaine ne dépend jamais de l'infrastructure.
Le socle est livré avec un exemple concret construit autour de l'aggregate Booking :
- Booking : une réservation avec
startDate/endDate(validés : début avant fin, pas de dates passées) etassetRefidentifiant la ressource réservée. - BookingItem : entité enfant liée en jointure, représentant une ligne de réservation.
L'exemple sollicite toute la stack : endpoints REST, validation de domaine, événements Kafka, persistance JPA, interface React. Il est conçu pour être remplacé par votre propre domaine, la structure reste, le métier change.
kore-hexagonal/
├── backend/
│ ├── domain/ # Java pur, zéro dépendance framework
│ │ ├── model/ # Aggregates, entités, value objects
│ │ ├── port/ # Interfaces de ports entrants et sortants
│ │ └── service/ # Services de domaine
│ ├── application/ # Handlers commandes/requêtes, cas d'usage
│ │ ├── command/
│ │ └── query/
│ └── infrastructure/ # Adaptateurs (JPA, Kafka, REST, Sécurité)
│ ├── persistence/
│ ├── messaging/
│ ├── web/
│ └── security/
├── frontend/ # React 19 + Vite + Tailwind
│ ├── src/
│ │ ├── pages/
│ │ ├── components/
│ │ └── api/
│ └── public/
├── docker/
│ ├── docker-compose.yml # Stack complète : app + Postgres + Kafka + monitoring
│ └── grafana/ # Dashboards provisionnés au démarrage
├── .github/
│ └── workflows/ # CI : build, tests, lint, push Docker
└── README.md
- Java 21+
- Docker & Docker Compose
- Node 20+ (frontend)
git clone https://github.com/alak8ba/kore-hexagonal.git
cd kore-hexagonal
docker compose -f docker/docker-compose.yml up -dLe backend démarre sur http://localhost:8080, le frontend sur http://localhost:5173, Grafana sur http://localhost:3000.
cd backend
./mvnw spring-boot:runcd frontend
npm install
npm run devPureté du domaine. Le module domain ne contient aucun import Spring ou JPA. Il compile sans le framework. Les tests sont rapides, sans infrastructure.
Un aggregate par commande. Les commandes ciblent un seul aggregate root. La coordination inter-aggregates passe par des événements de domaine consommés de façon asynchrone via Kafka.
Validation à la frontière. La validation des entrées (Jakarta Bean Validation) vit dans l'adaptateur REST. Les invariants de domaine sont imposés dans l'aggregate, jamais silencieusement.
Séparation du modèle de lecture. Les handlers de requêtes court-circuitent le domaine et interrogent des projections optimisées. Aucune logique de domaine ne s'exécute lors des lectures.
Observabilité d'abord. Chaque handler émet des métriques via Micrometer. Lag Kafka, santé JVM et latence HTTP sont câblés dans Grafana dès le départ.
GitHub Actions s'exécute à chaque push sur main et chaque pull request :
- Compilation et tests unitaires
- Tests d'intégration (Testcontainers, vrai Postgres et Kafka, sans mocks)
- Build de l'image Docker
- Push vers le registry (sur
mainuniquement)
Apache 2.0 — voir LICENSE.