Monorepositório com Go: 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

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



Monorepositório (monorepo) é uma abordagem de gerenciamento de código onde todos os projetos, bibliotecas e serviços são armazenados em um único repositório. Na comunidade Go, essa abordagem está ganhando popularidade devido à sua simplicidade e eficiência. Neste artigo, vamos explorar como organizar um projeto Go em um monorepositório na prática: desde a escolha da estrutura até a configuração de CI/CD.



Por que monorepositório para Go?



Go foi originalmente projetado como uma linguagem para grandes bases de código. Ferramentas como go mod e go work tornam o trabalho com monorepositório natural. As principais vantagens:



  • Simplificação de dependências: todos os módulos usam uma versão única de pacotes, sem conflitos de versão.
  • CI/CD unificado: um único arquivo de configuração para todos os serviços, mais fácil de manter.
  • Refatoração: alterações em uma API de biblioteca refletem imediatamente em todos os consumidores no repositório.
  • Padrões unificados: linters, formatadores e code reviews são aplicados a todo o código.


Estrutura do monorepositório: esquema comprovado



Vamos considerar uma estrutura que funciona muito bem para projetos Go de médio porte. Suponha que temos dois serviços: auth-service e api-gateway, além de bibliotecas compartilhadas.



my-project/├── apps/                    # Aplicações executáveis│   ├── auth-service/│   │   ├── cmd/│   │   │   └── main.go│   │   ├── internal/│   │   │   ├── handler/│   │   │   ├── service/│   │   │   └── repository/│   │   ├── go.mod│   │   └── go.sum│   └── api-gateway/│       ├── cmd/│       │   └── main.go│       ├── internal/│       │   ├── middleware/│       │   └── routes/│       ├── go.mod│       └── go.sum├── libs/                    # Bibliotecas compartilhadas│   ├── config/│   │   ├── config.go│   │   ├── go.mod│   │   └── go.sum│   ├── logger/│   │   ├── logger.go│   │   ├── go.mod│   │   └── go.sum│   └── db/│       ├── postgres.go│       ├── go.mod│       └── go.sum├── scripts/                 # Scripts para CI/CD e utilitários│   ├── build.sh│   └── test.sh├── go.work                  # Go Workspace (opcional)├── .golangci.yml            # Configuração do linter├── Makefile                 # Comandos gerais└── README.md


Elementos-chave da estrutura



  • apps/ — todas as aplicações executáveis. Cada aplicação tem seu próprio ponto de entrada (cmd/main.go) e seu próprio go.mod.
  • libs/ — bibliotecas de uso geral. Cada biblioteca é um módulo Go separado.
  • scripts/ — scripts auxiliares para build, teste e deploy.
  • go.work — arquivo para Go Workspace, simplifica o desenvolvimento local.


Configuração do Go Workspace para desenvolvimento local



Go 1.18+ suporta Workspace através do arquivo go.work. Isso permite referenciar localmente bibliotecas de libs/ sem publicá-las em um repositório remoto.



Crie o go.work na raiz do projeto:



go 1.22

use ( ./apps/auth-service ./apps/api-gateway ./libs/config ./libs/logger ./libs/db)


Agora, durante o desenvolvimento, você pode importar as bibliotecas diretamente:



// apps/auth-service/cmd/main.gopackage main

import ( "my-project/libs/config" "my-project/libs/logger")

func main() { cfg := config.Load() log := logger.New(cfg.LogLevel) log.Info("Auth service started")}


Nota importante: no go.mod de cada aplicação, a dependência da biblioteca deve apontar para o caminho local usando replace:



// apps/auth-service/go.modmodule github.com/company/my-project/a                

Blogs

Book Recommendations