Estrutura de pastas
Não existe "a" estrutura oficial em Go, mas existe uma convenção bem aceita pela comunidade (inspirada no golang-standards/project-layout). Para a maioria dos backends:
meu-servico/
├── cmd/
│ └── api/
│ └── main.go # Ponto de entrada. Só "amarra" as peças.
├── internal/ # Código privado do projeto.
│ ├── user/ # Domínio "user" (entity + service + interfaces)
│ │ ├── user.go # Struct, validações, regras puras
│ │ ├── service.go # Casos de uso
│ │ └── repository.go # Interface do repositório
│ ├── http/ # Adapter HTTP
│ │ ├── handler.go
│ │ └── router.go
│ ├── postgres/ # Adapter Postgres
│ │ └── user_repo.go
│ └── config/ # Carregamento de variáveis de ambiente
│ └── config.go
├── pkg/ # Código que pode ser usado por outros projetos (opcional)
├── migrations/ # Scripts SQL de migração
├── go.mod
└── go.sum
Por que internal/? Go tem uma regra mágica: qualquer pacote dentro de internal/ só pode ser importado pelo próprio módulo. Isso impede que outros projetos dependam da sua tripa interna. É proteção contra acoplamento acidental.
Por que cmd/? Porque um projeto pode ter mais de um binário (uma API, um worker, um CLI). Cada subpasta de cmd/ vira um executável.
Separação de responsabilidades na prática
A regra prática que evita 90% das tretas:
Se eu apagar o pacote X, o que mais quebra?
Se apagar o pacote postgres, o service deveria continuar compilando (porque ele depende da interface, não do postgres). Se apagar o service, o postgres deveria continuar compilando (ele só implementa uma interface). Se apagar o http, nem o service nem o postgres deveriam ligar.
Isso é o que chamamos de baixo acoplamento. E é o que faz um projeto durar 5 anos sem virar pesadelo.