Monorepositório com Kotlin: organização de código na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que um monorepositório em Kotlin?

\n

No desenvolvimento moderno com Kotlin, surge frequentemente um dilema: armazenar vários projetos relacionados (backend, microsserviços, bibliotecas, aplicativos Android) em repositórios separados (polirepositório) ou combiná-los em um único monorepositório. Um monorepositório é uma estratégia de armazenamento de código onde todos os componentes estão em um único sistema de controle de versão. Para projetos Kotlin, isso é especialmente relevante devido ao poderoso sistema de build Gradle e ao suporte nativo a multimódulos.

\n

Neste artigo, abordaremos os aspectos práticos da organização de um monorepositório com Kotlin: desde a estrutura de diretórios até a configuração de CI/CD e gerenciamento de dependências. Você aprenderá como evitar erros comuns e obter o máximo benefício de um repositório de código unificado.

\n\n

1. Estrutura do monorepositório: da teoria à prática

\n

Uma estrutura correta é a base de um monorepositório bem-sucedido. Vamos considerar um projeto típico que inclui uma API REST com Ktor, uma biblioteca para trabalhar com banco de dados e um aplicativo Android. Aqui está a hierarquia recomendada:

\n
my-monorepo/\n├── build.gradle.kts          # Arquivo de build raiz\n├── settings.gradle.kts       # Configuração dos módulos\n├── gradle.properties         # Propriedades comuns\n├── gradle/\n│   └── libs.versions.toml    # Catálogo de versões (Version Catalog)\n├── libs/                     # Bibliotecas compartilhadas\n│   ├── common-utils/         # Utilitários, extensões\n│   ├── common-db/            # Trabalho com BD (Exposed)\n│   └── common-dto/           # Data Transfer Objects\n├── services/                 # Aplicações servidoras\n│   ├── user-service/         # Microsserviço de usuários\n│   └── order-service/        # Microsserviço de pedidos\n└── apps/                     # Aplicações cliente\n    └── android-app/          # Aplicativo Android\n
\n

O elemento-chave é o settings.gradle.kts. Ele inclui todos os 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

Essa estrutura permite reutilizar facilmente o código entre serviços e cliente, além de gerenciar centralizadamente as versões das dependências.

\n\n

1.1. Version Catalog: gerenciamento de dependências

\n

Em um monorepositório, é fundamental evitar a duplicação de versões de bibliotecas. Use o Version Catalog (arquivo 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

Agora, em qualquer módulo, você pode escrever:

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

Isso garante que todos os módulos usem as mesmas versões e simplifica a atualização em massa.

\n\n

2. Organização prática dos módulos: Gradle Multi-Project

\n

Cada módulo do monorepositório é um subprojeto Gradle separado com seu próprio build.gradle.kts. Vamos considerar a configuração da 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

E aqui está um microsserviço típico com 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