Noções Básicas de Padrões Go
10 exemplos para você começar com padrões e idiomatismos Go - 7 básicos e 3 intermediários.
Busque em todas as páginas da documentação
10 exemplos para você começar com padrões e idiomatismos Go - 7 básicos e 3 intermediários.
go version reporta go1.26 ou posterior)go versionComponha o comportamento incorporando um tipo com os métodos necessários.
type LoggingHandler struct {
http.Handler
log *slog.Logger
}
func (h LoggingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.log.Info("request", "path", r.URL.Path)
h.Handler.ServeHTTP(w, r)
}ServeHTTP do manipulador internoRelacionado: Idiomatismos Go: Composição Sobre Herança - por que Go evita herança
Declare a interface onde você chama o comportamento, não onde você o implementa.
// pacote consumer
type Clock interface {
Now() time.Time
}
func TTL(c Clock, issued time.Time, ttl time.Duration) bool {
return c.Now().After(issued.Add(ttl))
}Clock, Store) não baseados em implementação (PostgresClock)Relacionado: Funções Construtoras e APIs de Pacote - conectando dependências através de construtores
Retorne valores inicializados de funções New em vez de exportar structs mutáveis.
type Counter struct {
n atomic.Int64
}
func NewCounter() *Counter { return &Counter{} }
func (c *Counter) Inc() { c.n.Add(1) }
func (c *Counter) Value() int64 { return c.n.Load() }New documenta a construção válida; o valor zero pode ser inválido para alguns tiposRelacionado: Funções Construtoras e APIs de Pacote - convenções New/Open
Modele configurações opcionais como funções que modificam o alvo durante a construção.
type Option func(*Server)
func WithPort(p int) Option {
return func(s *Server) { s.port = p }
}
func NewServer(opts ...Option) *Server {
s := &Server{port: 8080}
for _, opt := range opts {
opt(s)
}
return s
}New; os chamadores substituem apenas o que precisamNewServer(WithPort(3000), WithTLS(cert))Relacionado: Padrão de Opções Funcionais - análise completa do padrão
Envolva manipuladores com funções que executam antes e depois da lógica interna.
func withRequestID(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := uuid.NewString()
ctx := context.WithValue(r.Context(), requestIDKey, id)
w.Header().Set("X-Request-Id", id)
next.ServeHTTP(w, r.WithContext(ctx))
})
}func(http.Handler) http.Handler é nativa da biblioteca padrãoRelacionado: Padrões de Middleware e Decorador - encadeamento e ordenação
Isole o armazenamento atrás de uma interface da qual o serviço depende.
type User struct { ID string; Email string }
type UserRepo interface {
Get(ctx context.Context, id string) (User, error)
}
type Service struct { repo UserRepo }
func (s *Service) Email(ctx context.Context, id string) (string, error) {
u, err := s.repo.Get(ctx, id)
if err != nil { return "", err }
return u.Email, nil
}UserRepo em memória falso sem um banco de dadosRelacionado: Padrões de Camada de Repositório e Serviço - orientação de camadas
Inicialize recursos caros exatamente uma vez, com segurança sob concorrência.
var (
client *http.Client
once sync.Once
)
func HTTPClient() *http.Client {
once.Do(func() {
client = &http.Client{Timeout: 10 * time.Second}
})
return client
}once.Do executa a função exatamente uma vez entre goroutinesinit() - inicialização preguiçosa ou conexão de construtor é mais seguraRelacionado: Padrões sync.Once e Singleton - quando globais são aceitáveis
Valide opções compostas antes de retornar o valor construído.
func NewPool(size int, opts ...PoolOption) (*Pool, error) {
if size <= 0 {
return nil, errors.New("pool: size must be positive")
}
p := &Pool{size: size, idle: 30 * time.Second}
for _, opt := range opts {
if err := opt(p); err != nil {
return nil, err
}
}
return p, nil
}error de New sinaliza combinações inválidas precocementeerror quando a validação é por opçãoRelacionado: Padrão de Opções Funcionais - estratégias de validação
Conecte um serviço a partir de interfaces definidas no pacote do consumidor.
type Notifier interface {
Send(ctx context.Context, to, body string) error
}
type OrderService struct {
repo OrderRepo
notify Notifier
}
func NewOrderService(repo OrderRepo, notify Notifier) *OrderService {
return &OrderService{repo: repo, notify: notify}
}fakeNotifier e fakeRepo*OrderService concreto; aceite interfaces nos parâmetrosRelacionado: Padrões de Camada de Repositório e Serviço - testes com fakes
Componha middleware compatível com stdlib em um roteador chi.
r := chi.NewRouter()
r.Use(middleware.RequestID)
r.Use(middleware.RealIP)
r.Use(middleware.Recoverer)
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})r.Use registra middleware externo para todas as rotas no escoponet/http - manipuladores são http.HandlerFunc purosRelacionado: Padrões de Middleware e Decorador - encadeamento neutro em relação ao framework
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 (mais recente - verifique na compilação), gin (mais recente - verifique na compilação), echo (mais recente - verifique na compilação), google.golang.org/grpc (mais recente - verifique na compilação), sigs.k8s.io/controller-runtime (mais recente - verifique na compilação), kubebuilder (mais recente - verifique na compilação), tinygo (mais recente - verifique os alvos de placa na compilação), wazero (mais recente - verifique na compilação) e golangci-lint (mais recente - verifique na compilação).
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026