Enterprise Go: como escrever código que não envergonha mostrar ao CTO

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Go nos grandes negócios: por que já não é apenas uma "linguagem para microsserviços"

\n\n

Quando você ouve "Enterprise Go", o que vem à mente? Regulamentos corporativos chatos? Code reviews intermináveis? Ou, talvez, a sensação de que Go é apenas para startups e DevOps?

\n\n

Na verdade, Go no enterprise é um nível completamente diferente de disciplina e cultura de engenharia. Em grandes empresas (Uber, Dropbox, Salesforce, Twitch), não se escrevem apenas microsserviços em Go, mas plataformas inteiras que processam milhões de requisições por segundo. E aqui, "apenas funciona" não é suficiente.

\n\n

Neste artigo, vamos analisar as principais características do desenvolvimento em Go no enterprise: desde o design de pacotes até a logging em produção. Haverá muito código e o mínimo de enrolação.

\n\n

1. Arquitetura: não repita o erro "monólito em microsserviços"

\n\n

O problema mais comum que vejo em projetos Go de nível enterprise é a tentativa de transferir a arquitetura estilo Java para o Go. Resultado: centenas de interfaces desnecessárias e camadas de abstração que apenas atrasam o desenvolvimento.

\n\n

Regra "Package by feature, not by layer"

\n\n

Em vez de criar pastas /models, /handlers, /services — agrupe por domínios de negócio:

\n\n
myapp/\n├── cmd/\n│   └── server/\n│       └── main.go\n├── internal/\n│   ├── user/          # Tudo relacionado a usuários\n│   │   ├── handler.go\n│   │   ├── service.go\n│   │   ├── repository.go\n│   │   └── user.go    # Modelo de dados\n│   ├── payment/       # Tudo relacionado a pagamentos\n│   │   ├── handler.go\n│   │   ├── service.go\n│   │   ├── gateway.go\n│   │   └── payment.go\n│   └── pkg/           # Utilitários comuns\n└── go.mod
\n\n

Esta abordagem é uma das melhores práticas Go para enterprise. Ela reduz o acoplamento e torna o código previsível. Quando um novo desenvolvedor abre o projeto, ele vê imediatamente a lógica de negócio, e não camadas de abstração.

\n\n

Interfaces: aceite interfaces, retorne structs

\n\n

Este é um conselho clássico da comunidade Go, mas no enterprise é crítico. As interfaces devem ser pequenas (1-2 métodos) e definidas onde são usadas, não onde são implementadas.

\n\n
// RUIM: interface definida junto com a implementação\npackage user\n\ntype UserRepository interface {\n    FindByID(id string) (*User, error)\n    Save(user *User) error\n}\n\ntype postgresRepo struct { ... }\n\n// BOM: interface onde é necessária\npackage user\n\ntype Storage interface {\n    Get(id string) (*User, error)\n    Put(user *User) error\n}\n\ntype service struct {\n    db Storage\n}\n\nfunc NewService(db Storage) *service {\n    return &service{db: db}\n}
\n\n

Por que isso é importante? Porque no enterprise você frequentemente troca de backends (PostgreSQL -> CockroachDB, Redis -> KeyDB). Interfaces definidas no lado do consumidor permitem fazer isso sem dor.

\n\n

2. Tratamento de erros: pare de ignorar _

\n\n

Go não tem exceções, e isso é ótimo. Mas em projetos enterprise, erros não são apenas if err != nil. É toda uma cultura.

\n\n

Wrap ou não wrap?

\n\n

Use fmt.Errorf com %w para criar cadeias de erros. Isso permite preservar a pilha de chamadas e simplifica a depuração.

\n\n
func (s *service) ProcessOrder(ctx context.Context, orderID string) error {\n    order, err := s.orderRepo.Get(ctx, orderID)\n    if err != nil {\n        return fmt.Errorf("obtendo pedido %s: %w", orderID, err)\n    }\n\n    if err := s.paymentGateway.Charge(ctx, order.Amount); err != nil {\n        return fmt.Errorf("cobrando pedido %s: %w", orderID, err)\n    }\n\n    return nil\n}
\n\n

No nível superior (em handler/middleware), use errors.Is() e errors.As() para verificar tipos de erros:

\n\n
if errors.Is(err, ErrNotFo                

Blogs

Book Recommendations