Noções Básicas de Arquitetura Go
10 exemplos para você começar com Arquitetura - 7 básicos e 3 intermediários.
Busque em todas as páginas da documentação
10 exemplos para você começar com Arquitetura - 7 básicos e 3 intermediários.
go version).mkdir archdemo && cd archdemo && go mod init example.com/archdemo.Binários separados, implementação privada e código de biblioteca pública.
archdemo/
cmd/api/main.go
internal/service/
internal/store/
pkg/api/ # tipos de API compartilhados opcionais
cmd/ contém pacotes main - uma pasta por binário.internal/ oculta a implementação de importadores externos.pkg/ é opcional para bibliotecas que você deseja que outros módulos importem.Relacionado: Arquitetura em Go: Interfaces Pequenas, Dependências Explícitas - por que os limites importam
Passe dependências explicitamente em vez de globais.
package service
type Greeter struct {
prefix string
}
func New(prefix string) *Greeter {
return &Greeter{prefix: prefix}
}
func (g *Greeter) Hello(name string) string {
return g.prefix + ", " + name
}New valida as entradas e retorna uma struct pronta.Relacionado: Injeção de Dependência: wire, dig & Wiring Manual - dimensionando o wiring além do
mainfeito à mão
Defina o contrato onde ele é usado.
package handler
import "context"
type Lister interface {
List(ctx context.Context) ([]string, error)
}
type HTTP struct {
svc Lister
}
func New(svc Lister) *HTTP {
return &HTTP{svc: svc}
}Lister tem um método - fácil de mockar em testes de handler.internal/store sem importar HTTP.Traduza HTTP para chamadas de domínio; sem SQL em handlers.
package handler
import (
"encoding/json"
"net/http"
)
func (h *HTTP) List(w http.ResponseWriter, r *http.Request) {
items, err := h.svc.List(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
_ = json.NewEncoder(w).Encode(items)
}r.Context() para cancelamento e prazos.Relacionado: Camadas de Handler-Serviço-Repositório - fluxo completo de três camadas
Regras de negócios vivem entre HTTP e armazenamento.
package service
import (
"context"
"fmt"
)
type Repo interface {
All(ctx context.Context) ([]string, error)
}
type Service struct {
repo Repo
}
func New(repo Repo) *Service {
return &Service{repo: repo}
}
func (s *Service) List(ctx context.Context) ([]string, error) {
items, err := s.repo.All(ctx)
if err != nil {
return nil, fmt.Errorf("list: %w", err)
}
return items, nil
}%w) para observabilidade.List satisfaz a interface Lister do handler do exemplo 3.Isole a persistência atrás de uma pequena API.
package store
import "context"
type Memory struct {
data []string
}
func (m *Memory) All(ctx context.Context) ([]string, error) {
return append([]string(nil), m.data...), nil
}Conecte tipos concretos apenas em cmd/api/main.go.
package main
import (
"log"
"net/http"
"example.com/archdemo/internal/handler"
"example.com/archdemo/internal/service"
"example.com/archdemo/internal/store"
)
func main() {
repo := &store.Memory{data: []string{"alpha", "beta"}}
svc := service.New(repo)
h := handler.New(svc)
mux := http.NewServeMux()
mux.HandleFunc("GET /items", h.List)
log.Fatal(http.ListenAndServe(":8080", mux))
}main é o único lugar que conhece todos os tipos concretos.ServeMux.internal/Pacotes sob internal/ não podem ser importados fora da árvore pai.
// internal/store/pg.go
package store
// Apenas example.com/archdemo/... pode importar este pacote.
type PG struct{}internal.Relacionado: Arquitetura Limpa & Hexagonal em Go - portas na borda do domínio
Organize por capacidade quando os domínios forem claros.
internal/
billing/
service.go
handler.go
postgres.go
shipping/
...
internal/platform/) contêm helpers de logging e autenticação.Relacionado: Monolito vs Microserviços em Go - quando dividir binários
Registre por que você escolheu um layout antes que o debate se repita.
# ADR 0003: Camadas de handler-serviço-repositório
## Status
Aceito
## Contexto
Nova API HTTP; a equipe quer lógica de negócios testável.
## Decisão
Usar pacotes handler / service / repository com interfaces do lado do consumidor.
## Consequências
Mais pacotes; wiring explícito em main; testes unitários mais fáceis.docs/adr/ ou .adr/ na raiz do repositório.Relacionado: Registros de Decisão de Arquitetura para Equipes Go - decisões classificadas para serviços Go
Versões de Stack: Esta página foi escrita para Go 1.26.x (GC padrão Green Tea, 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: 18 de jul. de 2026