Monorepo avec Kotlin : organisation du code en pratique

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 : pourquoi un monorepo en Kotlin ?

\n

Dans le développement moderne en Kotlin, un dilemme se pose souvent : stocker plusieurs projets liés (backend, microservices, bibliothèques, applications Android) dans des dépôts séparés (polyrepo) ou les regrouper dans un seul monorepo. Le monorepo est une stratégie de stockage de code où tous les composants se trouvent dans un système de contrôle de version unique. Pour les projets Kotlin, cela est particulièrement pertinent grâce au puissant système de build Gradle et au support intégré du multi-module.

\n

Dans cet article, nous aborderons les aspects pratiques de l'organisation d'un monorepo avec Kotlin : de la structure des répertoires à la configuration du CI/CD et à la gestion des dépendances. Vous apprendrez à éviter les erreurs courantes et à tirer le meilleur parti d'un dépôt de code unique.

\n\n

1. Structure du monorepo : de la théorie à la pratique

\n

Une structure correcte est la base d'un monorepo réussi. Considérons un projet type comprenant une API REST avec Ktor, une bibliothèque pour interagir avec la base de données et une application Android. Voici la hiérarchie recommandée :

\n
my-monorepo/\n├── build.gradle.kts          # Fichier de build racine\n├── settings.gradle.kts       # Configuration des modules\n├── gradle.properties         # Propriétés communes\n├── gradle/\n│   └── libs.versions.toml    # Catalogue de versions (Version Catalog)\n├── libs/                     # Bibliothèques communes\n│   ├── common-utils/         # Utilitaires, extensions\n│   ├── common-db/            # Travail avec la BD (Exposed)\n│   └── common-dto/           # Data Transfer Objects\n├── services/                 # Applications serveur\n│   ├── user-service/         # Microservice utilisateurs\n│   └── order-service/        # Microservice commandes\n└── apps/                     # Applications clientes\n    └── android-app/          # Application Android\n
\n

L'élément clé est settings.gradle.kts. Il inclut tous les modules :

\n
rootProject.name = "my-monorepo"\n\ninclude("libs:common-utils")\ninclude("libs:common-db")\ninclude("libs:common-dto")\ninclude("services:user-service")\ninclude("services:order-service")\ninclude("apps:android-app")\n
\n

Cette structure permet de réutiliser facilement le code entre les services et le client, ainsi que de gérer centralement les versions des dépendances.

\n\n

1.1. Version Catalog : gestion des dépendances

\n

Dans un monorepo, il est essentiel d'éviter la duplication des versions de bibliothèques. Utilisez le Version Catalog (fichier gradle/libs.versions.toml) :

\n
[versions]\nkotlin = "2.0.21"\nktor = "3.0.3"\nexposed = "0.57.0"\n\n[libraries]\nktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }\nexposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" }\n\n[plugins]\nkotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }\n
\n

Désormais, dans n'importe quel module, vous pouvez écrire :

\n
dependencies {\n    implementation(libs.ktor.server.core)\n    implementation(libs.exposed.core)\n}\n
\n

Cela garantit que tous les modules utilisent les mêmes versions et simplifie les mises à jour massives.

\n\n

2. Organisation pratique des modules : Gradle Multi-Project

\n

Chaque module du monorepo est un sous-projet Gradle distinct avec son propre build.gradle.kts. Considérons la configuration de la bibliothèque common-utils :

\n
// libs/common-utils/build.gradle.kts\nplugins {\n    alias(libs.plugins.kotlin.jvm)\n}\n\ngroup = "com.mycompany.common"\nversion = "1.0.0"\n\ndependencies {\n    implementation(kotlin("stdlib"))\n    implementation(libs.kotlinx.coroutines)\n}\n
\n

Et voici un microservice type avec Ktor :

\n
// services/user-service/build.gradle.kts\nplugins {\n    alias(libs.plugins.kotlin.jvm)\n    alias(libs.plugins.ktor)\n}\n\ndependencies {\n    implementation(project(":libs:common-utils"))\n    implementation(project(":libs:common-dto"))\n    impl                

Blogs

Book Recommendations