Gin

Le framework web Go le plus rapide - base sur httprouter, allocation quasi nulle, parfait pour APIs haut debit

TL;DR

En une ligne : Gin est le framework web Go le plus rapide - API style Martini avec 40x meilleures performances, parfait pour les APIs à haut débit.

Forces principales :

  • Ultra rapide - basé sur httprouter, presque zéro allocation
  • Sans crash - récupération intégrée des panics
  • Validation JSON - tags struct pour binding et validation
  • Middleware - pipeline requête/réponse extensible

Core Concepts

Concept 1: Handlers

Les fonctions handler reçoivent un Context avec des utilitaires requête/réponse :

func getUser(c *gin.Context) {
    id := c.Param("id")           // Paramètre de chemin
    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 struct pour le parsing automatique des requêtes :

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

Fonctions qui s’exécutent avant/après les handlers :

// Middleware personnalisé
func Logger() gin.HandlerFunc {
    return func(c *gin.Context) {
        start := time.Now()
        c.Next()  // Traiter la requête
        log.Printf("%s %s %v", c.Request.Method, c.Request.URL, time.Since(start))
    }
}

r.Use(Logger())
r.Use(gin.Recovery())  // Récupération de panic intégrée

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()  // Inclut Logger et Recovery

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

    r.Run()  // Par défaut :8080
}

Run

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

Gotchas

Route groups for organization

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

    // Avec 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, "Bonjour %s", name)

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

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

// Redirection
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": "Utilisateur non trouvé"})
        return  // N'oubliez pas de return !
    }
    c.JSON(200, user)
}

gin.H is just a shortcut

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

// Équivalent à
c.JSON(200, map[string]any{"message": "ok"})

// Ou utilisez des structs pour la sécurité des types
type Response struct {
    Message string `json:"message"`
}
c.JSON(200, Response{Message: "ok"})

When to Use

Idéal pour :

  • APIs REST haute performance
  • Microservices
  • Applications temps réel
  • Équipes voulant simplicité + vitesse

Pas idéal pour :

  • Apps full-stack avec templates (utilisez Echo ou la bibliothèque standard)
  • Équipes nouvelles à Go
  • Projets nécessitant un ORM lourd (Gin n’est que du routing)

Comparaison :

FonctionnalitéGinEchoFiber
PerformanceTrès rapideTrès rapideLe plus rapide
APIStyle MartiniPropreStyle Express
CommunautéLa plus grandeGrandeEn croissance
FonctionnalitésMinimalesModéréesModérées

Next Steps

Cheatsheet

PatternCode
Route GETr.GET("/path", handler)
Route POSTr.POST("/path", handler)
Paramètre de cheminc.Param("id")
Paramètre de queryc.Query("name")
Query par défautc.DefaultQuery("page", "1")
Corps JSONc.ShouldBindJSON(&obj)
Réponse JSONc.JSON(200, gin.H{})
Groupe de routesr.Group("/api")
Middlewarer.Use(middleware)
Démarrer serveurr.Run(":8080")