GO — Estrutura de projetos
Tags: go, tips, architecture
Published: 2024-06-18 20:39:08

---
title: GO — Estrutura de projetos
published: true
description: 
tags: GoLang, Tips, softwarearchitecture
cover_image: https://media.licdn.com/dms/image/D4D12AQEM99NZeVMV7A/article-cover_image-shrink_720_1280/0/1703243547209?e=2147483647&v=beta&t=5mcy9qw0q3Ttz15cdvblS3D6ymUnBhXtEnE8yxiTTR0
# Use a ratio of 100:42 for best results.
# published_at: 2024-06-18 13:16 +0000
---
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.


<figure>
  <img src="https://miro.medium.com/v2/resize:fit:346/1*_zTyOnU7yCe9wl4a1AZlAg.png" alt="Imagem para um projeto simples com tudo na raiz">
  <figcaption>https://innovation.enova.com/gophercon-2018-how-do-you-structure-your-go-apps/</figcaption>
</figure>

## 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.

<figure>
  <img src="https://miro.medium.com/v2/resize:fit:300/0*6endj9h0yHQcrwpY.png" alt="Imagem mostrando que a infra esta envolvendo o domínio">
  <figcaption></figcaption>
</figure>

## Resultado

Para aplicação simples tento manter simples, contudo, quando o escopo fica um pouco maior, tento fazer uma leve diferenciação do que é “core”/domain do que é detalhe/infrastructure.

<figure>
  <img src="https://miro.medium.com/v2/resize:fit:201/1*cAqVTwIsa--ZW2IOKvi3WQ.png" alt="Imagem mostrando uma pasta para infra e outra para domínio">
  <figcaption></figcaption>
</figure>

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.

<figure>
  <img src="https://miro.medium.com/v2/resize:fit:521/1*EZWz2j9gY4NRSLY7ChQ9Jw.png" alt="Imagem mostrando os arquivos dentro da pasta domínio">
  <figcaption></figcaption>
</figure>

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.

<figure>
  <img src="https://miro.medium.com/v2/resize:fit:446/1*l0SOZMv7hsEYnkTbYTQU6g.png" alt="Imagem mostrando o tuttipet">
  <figcaption></figcaption>
</figure>

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)


<figure>
  <img src="https://miro.medium.com/v2/resize:fit:500/format:webp/1*rzfpebxLUEokne63Pvs5Ag.png" alt="Imagem mostrando as pasta dentro de infra">
  <figcaption></figcaption>
</figure>

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 dá 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/
https://go.dev/doc/effective_go#names
https://go.dev/blog/package-names

Post original: https://medium.com/@espigah/go-layout-do-projeto-18aacce8089d