Visão geral

Esta é uma estrutura básica para projetos de aplicativos Go. Não é um padrão oficialmente definido pela equipe central de desenvolvimento Go; é uma estrutura de diretórios comumente usada para projetos da comunidade Go.

Se você está aprendendo Go ou construindo um prova de conceito (PoC) ou um projeto pessoal simples, essa estrutura de projeto é muito complicada. Em vez disso, comece com uma estrutura verdadeiramente simples (apenas um arquivo main.go e go.mod são suficientes). Conforme seu projeto evolui, certifique-se de que sua estrutura de código seja boa, caso contrário, você acabará com um código bagunçado contendo muitas dependências ocultas e estado global. Quando mais pessoas se envolverem no projeto, você precisará de uma abordagem mais estruturada. Nesse caso, é importante introduzir uma maneira comum de gerenciar pacotes/bibliotecas. Quando você tem um projeto de código aberto ou sabe que outros projetos importam código do repositório do seu projeto, ter pacotes e código privados (também conhecidos como internal) se torna importante. Clone o repositório, mantenha as partes de que precisa e exclua todo o resto! Só porque algo existe não significa que você precisa usar tudo. Nenhum desses padrões é usado em todos os projetos. Até o padrão vendor não é universal.

Esta estrutura de projeto foi projetada intencionalmente para ser muito geral e não tenta impor uma estrutura específica de pacote Go.

Especificação do Diretório do Projeto Go

Abaixo está a especificação recomendada do diretório do projeto Go.

.
├── go.mod
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── go.mod
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website

Os significados de cada diretório são introduzidos abaixo.

/cmd

Os principais aplicativos do projeto, ou seja, o ponto de entrada dos programas. Os arquivos Go neste diretório normalmente geram arquivos executáveis. Em um projeto simples, um arquivo como /cmd/main.go pode servir como ponto de entrada.

O nome do diretório para cada aplicativo deve corresponder ao nome do arquivo executável desejado (por exemplo, /cmd/meuapp).

Não coloque muito código no diretório do aplicativo. Se você acha que o código pode ser importado e usado em outros projetos, coloque-o no diretório /pkg. Se o código não for reutilizável ou se você não quiser que outros o reutilizem, coloque o código no diretório /internal. Você ficará surpreso com o comportamento das outras pessoas, então expresse claramente sua intenção!

Geralmente há uma pequena função main que importa e chama o código dos diretórios /internal e /pkg, e nada mais.

/internal

Código de aplicativo e biblioteca privados. Este é o código que você não quer que outros importem para seus aplicativos ou bibliotecas. Observe que esse padrão de layout é imposto pelo próprio compilador Go. Para obter informações mais detalhadas, consulte as notas de lançamento para Go 1.4. Observe que isso não se limita ao diretório internal de nível superior. Você pode ter vários diretórios internal em qualquer nível da árvore do projeto.

Você pode optar por adicionar alguma estrutura adicional para pacotes internos para distinguir entre código interno compartilhado e não compartilhado. Isso não é necessário (especialmente para projetos menores), mas demonstrar visualmente o uso pretendido dos pacotes é uma boa prática. Seu código de aplicativo real pode ser colocado no diretório /internal/app (por exemplo, /internal/app/meuapp), e o código compartilhado para esses aplicativos pode ser colocado no diretório /internal/pkg (por exemplo, /internal/pkg/minhabibliotecaprivada).

/pkg

Código de biblioteca que pode ser usado por aplicativos externos (por exemplo, /pkg/minhabibliotecapublica). Outros projetos importarão essas bibliotecas e esperarão que funcionem corretamente, então pense cuidadosamente antes de colocar conteúdo aqui :-) Observe que o diretório internal é uma maneira melhor de garantir que pacotes privados não possam ser importados, pois é imposto pelo próprio Go. O diretório /pkg ainda é uma boa maneira de transmitir explicitamente que o código neste diretório é seguro para outros usarem.

Se o projeto de seu aplicativo for muito pequeno e o aninhamento em vários níveis não adicionar muito valor, também é aceitável não usá-lo (a menos que você realmente queira usá-lo :-)). Quando o projeto se tornar grande o suficiente e o diretório raiz se tornar muito movimentado, considere usá-lo (especialmente se você tiver muitos componentes de aplicativo não Go).

/vendor

Dependências do aplicativo (gerenciadas manualmente ou usando a sua ferramenta de gerenciamento de dependências preferida, como a funcionalidade integrada de Go Modules). O comando go mod vendor irá criar o diretório /vendor para você. Observe que se você não estiver usando a versão padrão habilitada do Go 1.14, pode ser necessário adicionar a flag -mod=vendor ao comando go build.

Se você estiver construindo uma biblioteca, por favor, não inclua as dependências do seu aplicativo.

Diretórios de Aplicativos de Serviço

/api

Especificações OpenAPI/Swagger, arquivos de esquema JSON, arquivos de definição de protocolo e diretórios de protocolo da API.

Diretórios de Aplicativos Web

/web

Componentes específicos para aplicativos web: ativos de site estático, modelos do lado do servidor e aplicativos de página única (SPAs).

Diretórios de Aplicativos Gerais

/configs

Modelos de arquivos de configuração ou configurações padrão.

Coloque seus arquivos de modelo confd ou consul-template aqui.

/init

Inicialização do sistema (systemd, upstart, sysv) e configurações do gerenciador de processos/daemon (runit, supervisord).

/scripts

Scripts para diversas operações de compilação, instalação, análise e outras.

/build

Empacotamento e integração contínua.

Coloque as configurações e scripts de empacotamento na nuvem (AMI), de contêiner (Docker), do sistema operacional (deb, rpm, pkg) no diretório /build/package.

Coloque as configurações e scripts de integração contínua (travis, circle, drone) no diretório /build/ci. Por favor, note que algumas ferramentas de integração contínua (como o Travis CI) são muito específicas sobre a localização de seus arquivos de configuração. Tente colocar os arquivos de configuração no diretório /build/ci e use links para conectá-los à localização esperada pelas ferramentas de integração contínua (se possível).

/deployments

Configurações de implantação e modelos para IaaS, PaaS, sistema e orquestração de contêiner (docker-compose, kubernetes/helm, terraform). Observe que em alguns repositórios (especialmente para aplicativos implantados usando Kubernetes), este diretório é chamado de /deploy.

/test

Outros aplicativos de teste externos e dados de teste. Fique à vontade para organizar o diretório /test da maneira que preferir. Para projetos maiores, faz sentido organizar os dados em subdiretórios. Por exemplo, você pode criar diretórios /test/data ou /test/testdata dentro de /test para fazer com que o Go ignore o conteúdo. Por favor, note que o Go também ignora diretórios ou arquivos que começam com "." ou "_", proporcionando maior flexibilidade ao nomear diretórios de dados de teste.

Outros Diretórios

/docs

Documentação de design e do usuário (além dos documentos godoc que você gera).

/tools

Ferramentas de suporte para este projeto. Por favor, note que estas ferramentas podem importar código dos diretórios /pkg e /internal.

/examples

Exemplos para aplicativos e/ou bibliotecas públicas.

/third_party

Ferramentas auxiliares externas, código bifurcado e outras ferramentas de utilidade de terceiros (por exemplo, Swagger UI).

/githooks

Githooks.

/assets

Ativos adicionais (imagens, logotipos, etc.) fornecidos com o repositório.

/website

Local para armazenar dados do site do projeto, caso você não esteja utilizando o GitHub Pages.

/src

Alguns projetos em Go podem ter uma pasta src, mas isso geralmente se deve aos desenvolvedores virem do mundo Java, onde é um padrão comum. Se possível, tente evitar adotar este padrão semelhante ao Java. Você realmente não quer que o seu código ou projeto Go pareça com Java :-)

Não confunda o diretório /src no nível do projeto com o diretório /src usado para o workspace Go, conforme descrito em Como Escrever Código Go. A variável de ambiente $GOPATH aponta para o seu workspace (atual) (por padrão, em sistemas não-Windows, ela aponta para o diretório $HOME/go). Este workspace inclui os diretórios de nível superior /pkg, /bin e /src. Seu projeto real será um subdiretório sob o diretório /src, então se o seu projeto tiver um diretório /src, o caminho do projeto parecerá assim: /algum/caminho/para/workspace/src/seu_projeto/src/seu_codigo.go. Por favor, note que a partir do Go 1.11, o seu projeto pode estar localizado fora do GOPATH, mas isso não significa que adotar este padrão de layout seja uma boa ideia.