Gin

El framework web mas rapido de Go - basado en httprouter, casi cero asignacion, perfecto para APIs de alto rendimiento

TL;DR

En una línea: Gin es el framework web más rápido de Go - API estilo Martini con 40x mejor rendimiento, perfecto para APIs de alto throughput.

Fortalezas principales:

  • Ultra rápido - basado en httprouter, casi cero asignaciones
  • A prueba de crashes - recuperación integrada de panics
  • Validación JSON - tags de struct para binding y validación
  • Middleware - pipeline request/response extensible

Core Concepts

Concept 1: Handlers

Las funciones handler reciben un Context con utilidades de request/response:

func getUser(c *gin.Context) {
    id := c.Param("id")           // Parámetro de ruta
    name := c.Query("name")       // Query string
    page := c.DefaultQuery("page", "1")

    c.JSON(200, gin.H{
        "id": id,
        "name": name,
    })
}

r.GET("/users/:id", getUser)

Concept 2: Binding & Validation

Tags de struct para parseo automático de requests:

type CreateUser struct {
    Name  string `json:"name" binding:"required"`
    Email string `json:"email" binding:"required,email"`
    Age   int    `json:"age" binding:"gte=0,lte=130"`
}

func createUser(c *gin.Context) {
    var user CreateUser
    if err := c.ShouldBindJSON(&user); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }
    c.JSON(201, user)
}

Concept 3: Middleware

Funciones que se ejecutan antes/después de los handlers:

// Middleware personalizado
func Logger() gin.HandlerFunc {
    return func(c *gin.Context) {
        start := time.Now()
        c.Next()  // Procesar request
        log.Printf("%s %s %v", c.Request.Method, c.Request.URL, time.Since(start))
    }
}

r.Use(Logger())
r.Use(gin.Recovery())  // Recuperación de panic integrada

Quick Start

Create Project

mkdir myapp && cd myapp
go mod init myapp
go get -u github.com/gin-gonic/gin

Create main.go

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()  // Incluye Logger y Recovery

    r.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{"message": "¡Hola Gin!"})
    })

    r.Run()  // Por defecto :8080
}

Run

go run main.go
# Abre http://localhost:8080

Gotchas

Route groups for organization

api := r.Group("/api")
{
    v1 := api.Group("/v1")
    {
        v1.GET("/users", getUsers)
        v1.POST("/users", createUser)
    }

    // Con middleware
    admin := api.Group("/admin", AuthMiddleware())
    {
        admin.GET("/stats", getStats)
    }
}

Different response types

// JSON
c.JSON(200, gin.H{"key": "value"})

// String
c.String(200, "Hola %s", name)

// Template HTML
c.HTML(200, "index.html", gin.H{"title": "Inicio"})

// Archivo
c.File("./path/to/file.pdf")

// Redirección
c.Redirect(302, "/new-location")

Error handling

func getUser(c *gin.Context) {
    user, err := findUser(c.Param("id"))
    if err != nil {
        c.AbortWithStatusJSON(404, gin.H{"error": "Usuario no encontrado"})
        return  // ¡No olvides hacer return!
    }
    c.JSON(200, user)
}

gin.H is just a shortcut

// gin.H es map[string]any
c.JSON(200, gin.H{"message": "ok"})

// Lo mismo que
c.JSON(200, map[string]any{"message": "ok"})

// O usa structs para seguridad de tipos
type Response struct {
    Message string `json:"message"`
}
c.JSON(200, Response{Message: "ok"})

When to Use

Ideal para:

  • APIs REST de alto rendimiento
  • Microservicios
  • Aplicaciones en tiempo real
  • Equipos que quieren simplicidad + velocidad

No ideal para:

  • Apps full-stack con templates (usa Echo o la biblioteca estándar)
  • Equipos nuevos en Go
  • Proyectos que necesitan ORM pesado (Gin es solo routing)

Comparación:

CaracterísticaGinEchoFiber
RendimientoMuy rápidoMuy rápidoEl más rápido
APIEstilo MartiniLimpiaEstilo Express
ComunidadLa más grandeGrandeCreciendo
CaracterísticasMínimasModeradasModeradas

Next Steps

Cheatsheet

PatrónCódigo
Ruta GETr.GET("/path", handler)
Ruta POSTr.POST("/path", handler)
Parámetro de rutac.Param("id")
Parámetro de queryc.Query("name")
Query por defectoc.DefaultQuery("page", "1")
Cuerpo JSONc.ShouldBindJSON(&obj)
Respuesta JSONc.JSON(200, gin.H{})
Grupo de rutasr.Group("/api")
Middlewarer.Use(middleware)
Iniciar servidorr.Run(":8080")