Gin: APIs JSON Rápidas e Binding
Gin otimiza APIs REST com muitas operações JSON com um roteador rápido, helpers *gin.Context e binding de structs suportado por go-playground/validator.
Busque em todas as páginas da documentação
Gin otimiza APIs REST com muitas operações JSON com um roteador rápido, helpers *gin.Context e binding de structs suportado por go-playground/validator.
Ele troca a portabilidade do stdlib handler por velocidade e ergonomia quando a maioria dos endpoints decodifica JSON, valida a entrada e renderiza respostas JSON.
Handlers Gin recebem *gin.Context, que expõe parâmetros, valores de query, métodos de binding e atalhos de resposta (JSON, XML, File).
Rotas agrupadas (RouterGroup) espelham layouts de API versionados.
Tags de binding declaram regras de validação na camada de transporte enquanto as regras de negócio permanecem nos serviços.
Cartão de receita de referência rápida - pronto para copiar e colar.
g := gin.New()
g.Use(gin.Recovery())
v1 := g.Group("/api/v1")
v1.POST("/users", createUser)
func createUser(c *gin.Context) {
var in createUserRequest
if err := c.ShouldBindJSON(&in); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
c.JSON(201, in)
}Quando usar isso:
package main
import (
"net/http"
"sync"
"github.com/gin-gonic/gin"
)
type createUserRequest struct {
Email string `json:"email" binding:"required,email"`
Name string `json:"name" binding:"required,min=2,max=64"`
}
type user struct {
ID int `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
}
type store struct {
mu sync.Mutex
next int
users map[int]user
}
func (s *store) create(email, name string) user {
s.mu.Lock()
defer s.mu.Unlock()
s.next++
u := user{ID: s.next, Email: email, Name: name}
s.users[u.ID] = u
return u
}
func main() {
gin.SetMode(gin.ReleaseMode)
g := gin.New()
g.Use(gin.Recovery())
g.Use(gin.Logger())
db := &store{users: make(map[int]user)}
api := g.Group("/api/v1")
{
api.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"status": "ok"})
})
api.POST("/users", func(c *gin.Context) {
var in createUserRequest
if err := c.ShouldBindJSON(&in); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
u := db.create(in.Email, in.Name)
c.JSON(http.StatusCreated, u)
})
api.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id")
c.JSON(http.StatusOK, gin.H{"id": id})
})
}
g.Run(":8080")
}O que isso demonstra:
gin.Default() em produção/api/v1 agrupadas com prefixo compartilhado:idc.Next() avança a cadeia dentro do middleware Gin.ShouldBind* lê o corpo uma vez e retorna erros sem escrever códigos de status automaticamente.binding mapeiam para regras do validator; validadores personalizados se registram no motor de binding do Gin.| Método | Uso Típico | Em caso de erro |
|---|---|---|
ShouldBindJSON | Corpos JSON | Retorna error apenas |
ShouldBindQuery | Parâmetros de Query | Retorna error apenas |
ShouldBindUri | Parâmetros de Path em struct | Retorna error apenas |
BindJSON | Corpos JSON | Escreve 400 automaticamente |
Prefira ShouldBind* em handlers para que você controle a forma da resposta.
c.JSON, c.XML, c.YAML e c.ProtoBuf definem o content type e codificam.
c.AbortWithStatusJSON para a cadeia de middleware após erros (comum em middleware de autenticação).
// Teste a lógica do handler extraindo uma função pura
func createUserHandler(s *store) gin.HandlerFunc {
return func(c *gin.Context) {
var in createUserRequest
if err := c.ShouldBindJSON(&in); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, s.create(in.Email, in.Name))
}
}Funções construtoras que retornam gin.HandlerFunc mantêm as dependências explícitas e testáveis.
BindJSON resposta dupla - BindJSON escreve 400 antes que você possa personalizar erros. Correção: use ShouldBindJSON e mapeie erros para o seu formato JSON de problema.gin.Default() em produção - O logger de depuração e alocações extras podem ser indesejáveis. Correção: gin.New() mais middleware escolhido.gin.Mode global - Executar acidentalmente o modo de depuração vaza erros verbosos. Correção: defina gin.SetMode(gin.ReleaseMode) em main e teste as configurações.gin.H grandes - Mapas não tipados escondem desvios de esquema. Correção: use structs de resposta para APIs públicas.gin.Context é difícil de portar. Correção: mantenha os handlers finos; chame funções Go puras com tipos de domínio.| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Echo | Ergonomia semelhante com helpers WebSocket integrados | Equipe já investida em plugins Gin |
| chi + validator | Handlers stdlib e camadas JSON explícitas | Você quer conveniência máxima de binding |
| stdlib + codegen | APIs OpenAPI-first com tipos gerados | Você quer um mínimo de ferramentas antecipadamente |
| Fiber | API semelhante a Express do Fiber (não stdlib) | Você requer compatibilidade com net/http |
Sim - Gin continua popular para APIs JSON em Go; verifique as versões dos módulos no momento da compilação de acordo com os pins do seu manifesto.
Mapeie validator.ValidationErrors para mensagens com escopo de campo em vez de retornar err.Error() bruto para clientes.
Sim - c.Request.Context() carrega deadlines; passe-o para chamadas de banco de dados e RPC.
Escreva middleware func(c *gin.Context) { ...; c.Next() } em grupos que precisam de autenticação; chame c.AbortWithStatusJSON em caso de falha.
Sim - c.HTML com LoadHTMLGlob; muitas APIs JSON pulam templates, mas UIs de administração podem coexistir.
Use httptest com gin.CreateTestContext ou inicialize um roteador e chame ServeHTTP em requisições gravadas.
c.FormFile e c.MultipartForm lidam com uploads; defina MaxMultipartMemory no engine para arquivos grandes.
api := g.Group("/api", authMiddleware) aplica middleware apenas às rotas registradas em api.
Sim - g.GET("/health", gin.WrapF(stdHandler)) ou gin.WrapH para valores http.Handler.
Ambos são fortes; Gin tem um ecossistema de middleware maior, Echo documenta prominentemente padrões de WebSockets e tratamento de erros.
Campos JSON opcionais frequentemente usam ponteiros (*string) para distinguir ausente de string vazia.
Use grupos de path (/v1, /v2) ou middleware de versionamento baseado em header; grupos mantêm middleware isolado por versão.
Versões da 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