Skill de Revisão de Design de API Go
Convenções de handler, erro e contexto para revisão automatizada - uma Skill de Agente em estilo de cookbook para auditar handlers HTTP e gRPC do Go 1.26 sem correções automáticas inseguras.
Busque em todas as páginas da documentação
Convenções de handler, erro e contexto para revisão automatizada - uma Skill de Agente em estilo de cookbook para auditar handlers HTTP e gRPC do Go 1.26 sem correções automáticas inseguras.
Produz uma checklist de revisão estruturada para handlers: propagação de context, mapeamento de erros, códigos de status, validação de requisição, ordenação de middleware e formato de resposta - cada achado com referências de arquivo e linha.
| Entrada | Por quê |
|---|---|
go.mod | Caminho do módulo, diretiva de versão Go |
| Pacotes afetados | Escopo de go test e lint |
| Escolha do roteador | ServeMux stdlib vs chi/gin/echo por ADR |
| ADR de tratamento de erros | Erros tipados vs padrão sentinela |
| ADR de autenticação/log | Expectativas de middleware |
| OpenAPI ou tabela de rotas | Métodos e caminhos esperados |
arquivo:linhago test ./pkg/..., golangci-lint run ./pkg/...r.Context() para todas as I/Os de saída - DB, cliente HTTP, gRPC.apierr dedicado, não ambos.errcheck, contextcheck) sem exceção de ADR.Cartão de receita de referência rápida - pronto para copiar e colar.
// Alvos de revisão (handler stdlib)
func getUser(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() // deve fluir para store.GetUser(ctx, id)
id := r.PathValue("id")
if id == "" {
writeError(w, apierr.BadRequest("id ausente"))
return
}
u, err := store.GetUser(ctx, id)
if err != nil {
writeError(w, mapStoreErr(err))
return
}
writeJSON(w, http.StatusOK, u)
}# Verificação após correções da revisão
go test ./internal/api/...
golangci-lint run ./internal/api/...
go vet ./internal/api/...Quando usar esta skill:
go list ./internal/api/...
grep -r "ServeHTTP\|HandleFunc\|chi\|gin\." internal/api/| Sinal | Ação |
|---|---|
Falta r.Context() em db.Query | Bloqueador |
http.Error(w, err.Error(), 500) na validação | Bloqueador |
Handler chama log.Printf e retorna texto de erro | Bloqueador |
Mistura de fmt.Errorf e sentinela no mesmo pacote | Aviso |
Verifique se todas as chamadas de saída recebem ctx derivado de r.Context():
// RUIM: context.Background() no handler
user, err := repo.Find(context.Background(), id)
// BOM: contexto com escopo de requisição
user, err := repo.Find(r.Context(), id)ReadHeaderTimeout, WriteTimeout) cancelam r.Context() - o downstream deve respeitá-lofunc mapStoreErr(err error) apierr.Response {
if errors.Is(err, store.ErrNotFound) {
return apierr.NotFound("usuário")
}
if errors.Is(err, store.ErrInvalid) {
return apierr.BadRequest("id de usuário inválido")
}
return apierr.Internal("falha na busca de usuário") // opaco para o cliente
}codes.InvalidArgument, codes.NotFound - veja padrões grpc-Go nas seções irmãs| Condição | Status | Corpo |
|---|---|---|
| Falha de validação | 400 ou 422 | { "error": "...", "code": "..." } |
| Falha de autenticação | 401 / 403 | Sem detalhes internos |
| Sucesso | 200 / 201 | Recurso ou lista conforme OpenAPI |
| Falha de servidor desconhecida | 500 | ID opaco + log do lado do servidor |
go test ./internal/api/... -count=1
golangci-lint run ./internal/api/...A ordenação de middleware afeta os achados da revisão.
Middleware de log e ID de requisição devem envolver a autenticação, que envolve os handlers de negócios.
A recuperação de pânico pertence à camada mais externa.
Agentes frequentemente inserem autenticação após handlers em rascunhos - sinalize como bloqueador.
A validação pertence à fronteira: parâmetros de caminho, query, corpo JSON.
Use encoding/json com decodificação estrita (DisallowUnknownFields) quando o ADR exigir.
Para chi/gin, confirme se a extração de parâmetros corresponde aos padrões de rota registrados.
Idempotência e métodos: GET e HEAD não devem mutar estado.
A política de POST para criar vs PUT para upsert deve corresponder ao OpenAPI.
O ServeMux do Go 1.22+ com padrões de método (GET /users/{id}) evita handlers acidentais para todos os métodos.
http.Error com err.Error() vaza detalhes de implementação e frequentemente usa status incorreto.context.WithTimeout aninhado sem defer cancel() - linters pegam alguns; revise manualmente.WriteHeader - o status é travado na primeira escrita; use um helper que define cabeçalhos uma vez.http.Client padrão não tem timeout - sinalize chamadas de saída de handlers usando http.DefaultClient.| Abordagem | Quando |
|---|---|
| Apenas revisão de design humana | Equipes pequenas, baixo tráfego |
| OPA / policy-as-code | Padrões HTTP em toda a organização |
| Linter OpenAPI em CI | APIs contract-first |
| Esta skill | Revisão de PR assistida com alinhamento de ADR da equipe |
Não. Apenas checklist de saída e sugestões de diff. O humano mescla após a passagem de go test e lint.
Sim para contexto, mapeamento de status (codes.*) e encapsulamento de erros. Seções específicas de HTTP pulam pacotes apenas de gRPC - colete entradas de roteador/proto primeiro.
Colete o framework nas entradas. Revise gin.HandlerFunc para propagação de c.Request.Context() e helper centralizado de erro c.JSON.
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: 16 de jul. de 2026