Estrutura de projetos Go
Tags: go, learning, productivity
Published: 2024-05-17 23:16:47

Quando estamos iniciando um novo projeto em uma nova linguagem, surgem algumas perguntas essenciais:

- "Qual estrutura devo utilizar para este projeto?"
- "Existe alguma convenção própria da linguagem?"
- "Há um padrão amplamente aceito pela comunidade?"

Este artigo busca responder a essas perguntas no contexto da linguagem Go.

A seguir, compilei as práticas mais comuns adotadas pela comunidade, incluindo padrões reforçados pelo compilador da linguagem.

## /cmd

Dentro deste diretório devemos criar subdiretórios que representaram cada executável do nosso projeto.

Uma conversão é de não colocarmos muito código dentro deste diretórios ou no arquivo principal. É comum ter uma pequena função `main` que importa e executa código dos outros diretórios como `internal` e `pkg` .

Exemplo de uso no [Kubernetes](https://github.com/kubernetes/kubernetes/tree/master/cmd).

## /internal

Diretório utilizado para código privado, que não é feito para ser utilizado por outros projetos. Esse padrão é aplicado pelo próprio compilador do Go.

Um adendo é que não estamos limitados somente ao top-level /internal, podemos ter quantos /internal quisermos em qualquer nível de camada da árvore do projeto.

A estrutura dentro do /internal é livre, podemos adicionar o que quisermos.

## /pkg

Diretório utilizado para código que pode ser compartilhado com outros projetos, podendo considerar código nesse diretório como público. É uma forma explícita de comunicar que o código aqui dentro é seguro de ser utilizado por terceiros.

Embora seja um padrão popular em diversos projetos ([containerd](https://github.com/containerd/containerd/tree/main/pkg), [istio](https://github.com/istio/istio/tree/master/pkg), [grafana](https://github.com/grafana/grafana/tree/master/pkg), etc), ele não é um padrão universalmente aceito, e alguns membros da comunidade Go até não o recomendam, como podemos ver na seguinte [discussão](https://github.com/golang-standards/project-layout/issues/10) sobre o tema.

## /vendor

Diretório dedicado a dependências da aplicação, normalmente é administrado por ferramentas como o `go mod` . O comando `go mod vendor` vai gerar este diretório automaticamente.

Uma observação importante é a de que não devemos commitar este diretório em nosso repositório Git, por exemplo, principalmente se estivermos desenvolvendo uma biblioteca pública.

## Outras divisões relevantes

### /api

Guardar specs OpenAPI, json schema, protocol buffers defs, etc

### /web ou /ui

Guardar arquivos estáticos da web, como arquivos HTML, CSS e JS, templates SSR (server side rendered) e SPAs.

### /deployments ou /deploy

Arquivos de orquestração de containers, configuração de IaaS ou PaaS, etc (docker compose, kubernetes, terraform)

### /test

Arquivos para teste automatizado e dados para testes.

## Adendo final

É importante ressaltar que esta estrutura não é  exclui a aplicação de qualquer arquitetura que seja, como uma Layered baseada em DDD ou Clean Arch, ou Event Driven.

A organização de pastas de um projeto é agnóstica à arquitetura implementada, embora muitas vezes possa refletir a mesma.

Com estas sugestões de organização, você pode iniciar seu projeto Go de maneira mais estruturada e em conformidade com as práticas aceitas pela comunidade.