Monorepository avec Java : organisation du code et bonnes pratiques

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : qu'est-ce qu'un monorepository et pourquoi en a-t-on besoin en Java



Dans le monde du développement Java, il existe deux approches principales pour stocker le code : le monorepository (monorepo) et le multirepository (multirepo). Un monorepository est une stratégie dans laquelle toutes les bases de code d'un projet (bibliothèques, services, utilitaires, configurations) sont stockées dans un seul dépôt. Pour les développeurs Java travaillant sur de grands systèmes d'entreprise ou des microservices, le monorepository devient une solution de plus en plus populaire.



Les avantages du monorepository en Java sont évidents :

  • Version unique des dépendances : Tous les modules utilisent une seule version des bibliothèques, ce qui élimine les conflits (classpath hell).
  • Refactoring simplifié : La modification d'une API dans un module est immédiatement visible dans tous les modules dépendants.
  • Historique transversal des modifications : Un seul commit peut contenir des modifications dans plusieurs modules, ce qui facilite le débogage.
  • Standardisation : Des règles unifiées de code style, de linting et de CI/CD pour l'ensemble du projet.


Cependant, le monorepository nécessite une organisation rigoureuse. Dans cet article, nous allons voir comment structurer correctement un projet Java dans un monorepository, en utilisant Maven et Gradle.



Partie principale : organisation d'un monorepository en Java



1. Structure des répertoires : approche modulaire



La base d'un monorepository est une structure modulaire. Chaque module représente une unité indépendante (bibliothèque, service, utilitaire). Considérons une structure typique pour un projet Java :



my-monorepo/├── build.gradle          # Fichier de build racine (Gradle)├── settings.gradle       # Liste des modules├── gradle.properties     # Paramètres communs├── gradle/│   └── wrapper/├── common/               # Bibliothèques communes│   ├── common-utils/     # Utilitaires (chaînes, dates)│   └── common-dto/       # DTO pour l'échange de données├── services/             # Microservices│   ├── user-service/     # Service utilisateur│   └── order-service/    # Service de commandes├── libs/                 # Bibliothèques internes│   └── logging-lib/      # Bibliothèque de logging├── tests/                # Tests d'intégration/de bout en bout│   └── e2e-tests/└── buildSrc/             # Plugins et configurations communs


Chaque module à l'intérieur a une structure standard Maven/Gradle :

user-service/├── build.gradle├── src/│   ├── main/│   │   ├── java/│   │   │   └── com/example/user/│   │   │       ├── controller/│   │   │       ├── service/│   │   │       └── repository/│   │   └── resources/│   │       └── application.yml│   └── test/│       └── java/└── Dockerfile


2. Gestion des dépendances : Maven BOM et Gradle Version Catalog



Le principal problème d'un monorepository est la synchronisation des versions des dépendances. En Java, cela se résout de deux manières.



Option 1 : Maven BOM (Bill of Materials)

Un POM racine est créé, qui déclare toutes les versions des dépendances. Les modules enfants utilisent dependencyManagement :



<!-- pom.xml (racine) --><dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-dependencies</artifactId>            <version>3.2.0</version>            <type>pom</type>            <scope>import</scope>        </dependency>        <dependency>            <groupId>com.example</groupId>            <artifactId>common-utils</artifactId>            <version>1.0.0</version>        </dependency>    </dependencies></dependencyManagement>


Option 2 : Gradle Version Catalog

Dans le fichier gradle/libs.versi

Blogs

Book Recommendations