GO — Layout do projeto
Comecei a programar usando golang de verdade esse ano (2022), e a coisa que logo fiz foi procurar referências de como seria a melhor forma de evoluir minha estrutura para o projeto. Esse post será só mais um dentre tantos outros que falam do mesmo assunto, e, talvez até por isso, resolvi escrevê-lo.
Primeiro que golang já é todo diferentoso na forma que lida com pastas/packages, e, pra melhorar, tem uma essência bastante opinativa, com muitas docs oficiais informando como seria o “goway” de se fazer algo (cheio de não me toque), entretanto, na forma que você vai organizar seus arquivos e pastas, não tem bem um direcionamento, então, meio que cada um dá a sua interpretação de mundo pra essa parte.
Irei dividir esse post em 3 referências e depois mostrar como ficou a mistura dessas referências no projeto.
Primeira referência
Um sistema complexo que funciona invariavelmente evoluiu de um sistema simples que funcionou.
Lei de Gall
Para pequenas aplicação a estrutura do projeto deve ser simples.
Segunda referência
A “comunidade” fez um levantamento de um conjunto de padrões de layout de projeto históricos e emergentes comuns no ecossistema Go. Nesse levante tem muita coisa bacana, mas o que me chamou a atenção foram as pastas /cmd e /internal
/cmd
Principais aplicações para este projeto.
O nome do diretório para cada aplicativo deve corresponder ao nome do executável que você deseja ter(ex.: /cmd/myapp
).
/internal
Aplicativo privado e código de biblioteca. Este é o código que você não quer que outros importem em seus aplicativos ou bibliotecas. Observe que esse padrão de layout é imposto pelo próprio compilador Go.
Terceira referência
Arquiteturas que separam melhor os “detalhes” do que realmente entrega valor.
Resultado
Para aplicação simples tento manter simples, contudo, quando o escopo fica um poco maior, tento fazer uma leve diferenciação do que é “core”/domain do que é detalhe/infrastructure.
Notem que no cmd não tenho a pasta tuttipet, como sugere o projeto de referência. No começo eu tentei usar o padrão sugerido, mas como esta API já saiu com uma interface de linha de comando e um provider para terraform resolvi deixar desta forma.
Dando um rápido zoom no core. Tento ser simplista aqui e não criar pastas. Mantenho somente 1 ponto de contato com o mundo externo (main.go), o que for generalizado tem seu próprio arquivo e o que não for fica dentro do seu contexto, simples.
Com o tuttipet.New (curto, conciso e evocativo) a camada “suja” consegue interagir com os usecases (acho a palavra usecase mais fácil de assimilar que interactor)
Dando um rápido zoom nos detalhes. Aqui simplesmente estão as ferramentas pelas quais o domínio vai conseguir o seu sucesso.
Conclusão
Ainda sou pimpolho nos caminho que golang oferece, ainda tateando o que da pra fazer com ele, no entanto, mesmo sem gostar do jeitinho Go de fazer algumas coisa, o mesmo tem se mostrado bastante simples e robusto.
Resumo, tentando deixar simples quando dê e se ficar complexo de mais … volto pra prancheta.
Outras referências
https://dev.to/booscaaa/implementando-clean-architecture-com-golang-4n0a
https://github.com/golang-standards/project-layout
https://blog.boot.dev/golang/golang-project-structure/
https://github.com/bnkamalesh/goapp
https://www.wolfe.id.au/2020/03/10/how-do-i-structure-my-go-project/
https://blog.logrocket.com/flat-structure-vs-layered-architecture-structuring-your-go-app/
https://developer20.com/how-to-structure-go-code/
https://dev.to/jinxankit/go-project-structure-and-guidelines-4ccm
https://github.com/bxcodec/go-clean-arch
https://golangexample.com/example-go-clean-architecture-folder-pattern/
https://www.calhoun.io/flat-application-structure/