Com net/http puro dá para fazer uma API em Go, mas ler JSON exige configurar o decoder à mão e pegar um ID da URL vira manipulação de string. O Gin resolve essas partes. Aprender o net/http primeiro ajuda a entender o que o framework faz por baixo.
O que o Gin traz
Segundo o README, o Gin tem um roteador sem alocações, middleware (autenticação, log, CORS), um middleware de recuperação que evita derrubar o servidor, vinculação e validação automática de JSON, agrupamento de rotas e tratamento centralizado de erros. O README afirma ser “até 40 vezes mais rápido” que APIs no estilo do Martini, graças ao httprouter. É uma comparação com um framework antigo, não com o net/http. A versão mais recente que vi é a 1.12.0, e ela exige Go 1.26 ou mais novo.
Instalação
mkdir aprendendo-gin && cd aprendendo-gin
go mod init meunome/gin
go get -u github.com/gin-gonic/gin
Hello World
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{"mensagem": "pong"})
})
r.Run() // porta 8080 por padrão
}
Rode com go run main.go e acesse localhost:8080/ping. O c.JSON já define o cabeçalho e codifica a resposta.
Recebendo JSON
type Produto struct {
Nome string `json:"nome" binding:"required"`
Preco float64 `json:"preco" binding:"required"`
}
r.POST("/produtos", func(c *gin.Context) {
var p Produto
if err := c.ShouldBindJSON(&p); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"erro": err.Error()})
return
}
c.JSON(http.StatusCreated, gin.H{"produto": p})
})
Enviar um JSON sem o campo preco faz o Gin rejeitar a requisição. Uma pegadinha: para números, required trata o valor zero como ausente, então "preco": 0 também é recusado. Se zero for válido no seu caso, use um ponteiro (*float64).
Agrupando rotas e parâmetros
v1 := r.Group("/api/v1")
{
v1.GET("/usuarios/:id", func(c *gin.Context) {
c.JSON(200, gin.H{"usuario_id": c.Param("id")})
})
}
Framework ou biblioteca padrão?
Quem prefere só net/http tem argumento para microsserviços pequenos. Em aplicações maiores, com equipe grande, o Gin padroniza como se lê JSON, valida e trata erros. O banco de dados não muda: a camada de conexão continua a mesma, e o Gin só substitui o roteamento.
Se quiser comparar com um framework de sintaxe mais próxima da do Express, veja o tutorial de Go Fiber.
Exercício: pegue uma API em net/http e troque o roteamento manual pelo Gin, usando ShouldBindJSON no lugar de decodificar o corpo.