Introduction au monorepository avec Kotlin
Le développement moderne d'applications complexes est souvent confronté au problème de la gestion du code. Le choix entre un monorepository et un multirepository est l'une des décisions architecturales clés. Dans cet article, nous allons voir comment organiser un monorepository avec Kotlin, en utilisant les meilleures pratiques et les outils modernes.
Un monorepository (monorepo) est une approche où tous les projets, bibliothèques et services sont stockés dans un seul dépôt. Pour les développeurs Kotlin, cela est particulièrement pertinent grâce au puissant système de build Gradle et à la possibilité d'utiliser du code commun entre différents modules.
Avantages du monorepository pour les projets Kotlin
Avant de passer à l'organisation, examinons les principaux avantages du monorepository pour Kotlin :
- Version unique des dépendances — tous les modules utilisent une seule version de Kotlin, des bibliothèques et des plugins, ce qui élimine les conflits de versions.
- Refactoring simplifié — les modifications dans une bibliothèque commune sont automatiquement vérifiées par tous les modules dépendants.
- Configuration centralisée — les paramètres communs de Gradle, les linters et le CI/CD sont configurés une seule fois.
- Commits atomiques — les modifications liées dans différents modules peuvent être effectuées en un seul commit.
- Réutilisation du code — les utilitaires communs, les DTO et la logique métier sont facilement accessibles à tous les projets.
Structure du monorepository avec Kotlin et Gradle
Examinons la structure de répertoires optimale pour un monorepository Kotlin utilisant Gradle Multi-Module :
my-monorepo/├── build.gradle.kts # Fichier build racine├── settings.gradle.kts # Configuration des modules├── gradle.properties # Propriétés communes├── gradle/│ └── libs.versions.toml # Version Catalog├── modules/│ ├── common/ # Utilitaires et modèles communs│ ├── domain/ # Logique métier│ ├── data/ # Couche de données (API, BD)│ ├── service-a/ # Microservice A│ ├── service-b/ # Microservice B│ └── shared-test/ # Utilitaires de test communs├── apps/│ ├── backend/ # Application principale│ └── cli-tool/ # Outil CLI└── config/ ├── checkstyle/ # Configuration des linters └── docker/ # Dockerfile pour les servicesConfiguration de settings.gradle.kts
Le fichier settings.gradle.kts définit tous les modules du projet :
rootProject.name = "my-monorepo"
// Inclure tous les modulesinclude( ":modules:common", ":modules:domain", ":modules:data", ":modules:service-a", ":modules:service-b", ":apps:backend", ":apps:cli-tool")
// Plugin pour la gestion des versionspluginManagement { repositories { gradlePluginPortal() mavenCentral() }}Utilisation du Version Catalog (libs.versions.toml)
Pour une gestion centralisée des dépendances, nous utilisons gradle/libs.versions.toml :
[versions]kotlin = "1.9.22"coroutines = "1.7.3"ktor = "2.3.7"exposed = "0.44.1"
[libraries]kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" }
[plugins]kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }Exemple de build.gradle.kts pour le module common
plugins { alias(libs.plugins.kotlin.jvm)}
depend