Melhores Práticas Essenciais para Bibliotecas Go
Um resumo condensado das 25 práticas mais importantes para bibliotecas essenciais, extraídas de todas as páginas desta seção.
Busque em todas as páginas da documentação
Um resumo condensado das 25 práticas mais importantes para bibliotecas essenciais, extraídas de todas as páginas desta seção.
Stdlib primeiro: Utilize log/slog, net/http e database/sql antes de adicionar módulos; documente a lacuna de capacidade ao importar.
Uma biblioteca por preocupação: Escolha um logger, um router e um carregador de configuração por serviço; ferramentas duplicadas inflacionam a integração e a superfície de CVEs.
Revise diffs de go.mod: Trate novas linhas de require como código de produção em revisão de PR; execute go mod tidy antes de mesclar.
Execute govulncheck em CI: Escaneie o grafo completo de módulos após alterações de dependência; bloqueie mesclagens em caminhos críticos definidos por sua política.
Verifique arquivos LICENSE: Confirme a compatibilidade com BSD/MIT/Apache antes de importar; revisão legal para LGPL ou termos incomuns.
Inspecione sinais de manutenção: Prefira bibliotecas com lançamentos recentes, issues responsivas e propriedade clara em vez de estrelas estagnadas no GitHub.
Meça a profundidade transitiva: Execute go list -m all ao avaliar importações; grafos rasos envelhecem melhor do que forks surpresa.
Mantenha bibliotecas nas bordas: Pacotes de domínio aceitam interfaces; zap, chi e viper param em handlers, main e internal/config.
Injete loggers: Passe *slog.Logger ou *zap.Logger de main; evite padrões de nível de pacote que testes não podem substituir.
Estabilize nomes de campos de log: Use chaves consistentes (trace_id, err, user_id) entre serviços para que migrações entre zap, zerolog e slog não quebrem consultas.
Padrão de novos serviços para slog: Adote zap ou zerolog apenas quando benchmarks em handlers reais provarem gargalos de alocação.
Carregue a configuração uma vez em main: Desmaterialize viper ou envconfig em structs tipadas; nunca espalhe viper.GetString por pacotes de negócios.
Valide segredos necessários na inicialização: Falhe rapidamente quando DSNs ou chaves de API estiverem vazios; não descubra configurações ausentes no primeiro tráfego.
Documente tabelas de variáveis de ambiente: Espelhe tags de struct em README e comentários Helm para que os operadores saibam as chaves necessárias sem ler o código.
Use testify apenas em testes: Mantenha asserções em _test.go; consumidores de bibliotecas não devem herdar testify transitivamente de sua API.
Prefira interfaces pequenas para mocks: Defina interfaces de um ou dois métodos no consumidor; gere mocks com mockery apenas quando os contratos de chamada importarem.
Regenere Wire após mudanças de provedor: Execute wire ./... em CI e falhe em diffs de wire_gen.go desatualizados quando os construtores mudarem.
Divida conjuntos de injetores Wire: Use conjuntos de provedores separados por binário (API, worker) em vez de um único inicializador de grafo principal.
Valide na borda HTTP: Execute validator em DTOs após a decodificação JSON; mantenha invariantes de negócios em serviços, não apenas em tags.
Execute migrações em jobs de deploy: Aplique golang-migrate up antes que o novo código sirva tráfego; nunca migre dentro de manipuladores de requisição.
Mantenha o schema do sqlc sincronizado: Aponte sqlc para a mesma pasta de migração que a CI usa; regenere Go quando queries ou colunas mudarem.
Proteja a cardinalidade do Prometheus: Rotule métricas com padrões de rota, não URLs brutos com IDs; limite dimensões de rótulos em ADRs.
Desligue exportadores OTel em SIGTERM: Chame TracerProvider.Shutdown durante o esvaziamento gracioso para que os spans sejam descarregados antes da saída.
Exponha /metrics com segurança: Escaneie em uma porta de administração ou atrás de política de rede; não publique métricas operacionais na internet pública sem autenticação.
Registre escolhas de bibliotecas em ADRs: Documente por que chi em vez de Gin, slog em vez de zap, ou sqlc em vez de ORM para que equipes futuras entendam as restrições e caminhos de migração.
Após grandes lançamentos do Go e quando os avisos de segurança afetarem seu grafo - pelo menos trimestralmente para pilhas de propriedade da plataforma.
Stdlib primeiro mais dependências mínimas - mantém as compilações rápidas, o raio de explosão de CVEs pequeno e a integração previsível.
Prefira listas de permissões com exceções via ADR em vez de proibições ad hoc por serviço sem governança.
Bibliotecas enfrentam limites de dependência transitiva mais rigorosos; consumidores herdam todo o seu grafo.
Quando a lógica tem aproximadamente trinta linhas ou menos, foi revisada de segurança e é improvável que precise de correções upstream - documente a decisão de fork.
Sim para higiene de logging e configuração; CLIs podem pular routers HTTP e métricas, a menos que exponham servidores.
As regras semver de módulos complementam essas práticas de biblioteca - use ambas nos templates de PR.
Chaves de campo inconsistentes entre serviços, o que quebra dashboards durante migrações de bibliotecas.
Apenas quando a política exigir; vendoring não remove a necessidade de verificar versões e executar govulncheck.
Artigos sobre Slog, Prometheus RED e tracing OTel se aprofundam; esta seção nomeia as escolhas de biblioteca nas bordas.
Versões da Stack: Esta página foi escrita para Go 1.26.x (padrão Green Tea GC, go fix modernizers - verifique o patch na compilação), chi (última versão - verifique na compilação), gin (última versão - verifique na compilação), echo (última versão - verifique na compilação), google.golang.org/grpc (última versão - verifique na compilação), sigs.k8s.io/controller-runtime (última versão - verifique na compilação), kubebuilder (última versão - verifique na compilação), tinygo (última versão - verifique os alvos de placa na compilação), wazero (última versão - verifique na compilação) e golangci-lint (última versão - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026