Monorepositorio con Kotlin: organización del código en la práctica

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿por qué un monorepositorio en Kotlin?

\n

En el desarrollo moderno con Kotlin, a menudo surge el dilema: ¿almacenar varios proyectos relacionados (backend, microservicios, bibliotecas, aplicaciones Android) en repositorios separados (polirepositorio) o combinarlos en un solo monorepositorio? Un monorepositorio es una estrategia de almacenamiento de código donde todos los componentes se encuentran en un único sistema de control de versiones. Para proyectos Kotlin, esto es especialmente relevante gracias al potente sistema de compilación Gradle y al soporte integrado para múltiples módulos.

\n

En este artículo, analizaremos los aspectos prácticos de organizar un monorepositorio con Kotlin: desde la estructura de directorios hasta la configuración de CI/CD y la gestión de dependencias. Aprenderá cómo evitar errores típicos y obtener el máximo beneficio de un repositorio de código unificado.

\n\n

1. Estructura del monorepositorio: de la teoría a la práctica

\n

Una estructura correcta es la base de un monorepositorio exitoso. Consideremos un proyecto típico que incluye una API REST con Ktor, una biblioteca para trabajar con la base de datos y una aplicación Android. Aquí hay una jerarquía recomendada:

\n
my-monorepo/\n├── build.gradle.kts          # Archivo de compilación raíz\n├── settings.gradle.kts       # Configuración de módulos\n├── gradle.properties         # Propiedades comunes\n├── gradle/\n│   └── libs.versions.toml    # Catálogo de versiones (Version Catalog)\n├── libs/                     # Bibliotecas comunes\n│   ├── common-utils/         # Utilidades, extensiones\n│   ├── common-db/            # Trabajo con BD (Exposed)\n│   └── common-dto/           # Data Transfer Objects\n├── services/                 # Aplicaciones de servidor\n│   ├── user-service/         # Microservicio de usuarios\n│   └── order-service/        # Microservicio de pedidos\n└── apps/                     # Aplicaciones cliente\n    └── android-app/          # Aplicación Android\n
\n

El elemento clave es settings.gradle.kts. Incluye todos los módulos:

\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

Esta estructura permite reutilizar fácilmente el código entre servicios y cliente, así como gestionar centralizadamente las versiones de las dependencias.

\n\n

1.1. Version Catalog: gestión de dependencias

\n

En un monorepositorio es crítico evitar la duplicación de versiones de bibliotecas. Utilice Version Catalog (archivo 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

Ahora, en cualquier módulo puede escribir:

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

Esto garantiza que todos los módulos usen las mismas versiones y simplifica las actualizaciones masivas.

\n\n

2. Organización práctica de módulos: Gradle Multi-Project

\n

Cada módulo del monorepositorio es un subproyecto independiente de Gradle con su propio build.gradle.kts. Veamos la configuración de la biblioteca 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

Y aquí un microservicio típico en 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