Construire des API REST en Go : Guide complet
Construisez des API REST prêtes pour la production avec l'écosystème robuste de Go
La construction d’API REST haute performance avec Go est devenue une approche standard pour alimenter les systèmes de Google, Uber, Dropbox et d’innombrables startups.
La simplicité de Go, sa forte prise en charge de la concurrence et sa compilation rapide en font un choix idéal pour les microservices et le développement backend.
Cette image géniale est générée par FLUX.1-Kontext-dev: Image Augmentation AI Model.
Pourquoi choisir Go pour le développement d’API ?
Go offre plusieurs avantages convaincants pour le développement d’API :
Performance et Efficacité : Go se compile en code machine natif, offrant des performances proches de C sans la complexité. Sa gestion efficace de la mémoire et ses tailles de binaires réduites en font un choix parfait pour les déploiements conteneurisés.
Concurrence Intégrée : Les goroutines et les canaux (channels) simplifient la gestion de milliers de requêtes simultanées. Vous pouvez traiter plusieurs appels d’API simultanément sans code de threadage complexe.
Bibliothèque Standard Robuste : Le package net/http fournit un serveur HTTP prêt pour la production dès l’installation. Vous pouvez construire des API complètes sans aucune dépendance externe.
Compilation Rapide : La vitesse de compilation de Go permet une itération rapide pendant le développement. Les grands projets se compilent en quelques secondes, pas en minutes.
Typage Statique avec Simplicité : Le système de types de Go détecte les erreurs à la compilation tout en maintenant la clarté du code. Le langage possède un ensemble de fonctionnalités restreint, facile à apprendre.
Approches pour construire des API en Go
Utilisation de la Bibliothèque Standard
La bibliothèque standard de Go fournit tout ce qui est nécessaire pour le développement d’API de base. Voici un exemple minimal :
package main
import (
"encoding/json"
"log"
"net/http"
)
type Response struct {
Message string `json:"message"`
Status int `json:"status"`
}
func healthHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(Response{
Message: "API is healthy",
Status: 200,
})
}
func main() {
http.HandleFunc("/health", healthHandler)
log.Println("Server starting on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Cette approche offre un contrôle total et zéro dépendance. Elle est idéale pour les API simples ou lorsque vous souhaitez comprendre la gestion HTTP à un niveau fondamental.
Frameworks Web Go Populaires
Bien que la bibliothèque standard soit puissante, les frameworks peuvent accélérer le développement :
Gin : Le framework web Go le plus populaire, connu pour ses performances et sa facilité d’utilisation. Il offre un routage pratique, une prise en charge du middleware et une validation des requêtes.
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id")
c.JSON(http.StatusOK, gin.H{
"user_id": id,
"name": "John Doe",
})
})
r.Run(":8080")
}
Chi : Un routeur léger et idiomatique qui semble être une extension de la bibliothèque standard. Il est particulièrement bon pour construire des services RESTful avec un routage imbriqué.
Echo : Framework haute performance avec un middleware étendu et une excellente documentation. Il est optimisé pour la vitesse tout en restant convivial pour les développeurs.
Fiber : Inspiré par Express.js, construit sur Fasthttp. C’est l’option la plus rapide, mais elle utilise une implémentation HTTP différente de celle de la bibliothèque standard.
Modèles Architecturaux
Lors du travail avec des opérations de base de données en Go, vous devrez considérer votre stratégie ORM. Différents projets ont comparé des approches comme GORM, Ent, Bun et sqlc, chacune offrant différents compromis entre productivité des développeurs et performance.
Architecture en Couches
Structurez votre API avec une séparation claire des préoccupations :
// Handler Layer - HTTP concerns
type UserHandler struct {
service *UserService
}
func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
user, err := h.service.GetByID(r.Context(), id)
if err != nil {
respondError(w, err)
return
}
respondJSON(w, user)
}
// Service Layer - Business logic
type UserService struct {
repo *UserRepository
}
func (s *UserService) GetByID(ctx context.Context, id string) (*User, error) {
// Validate, transform, apply business rules
return s.repo.FindByID(ctx, id)
}
// Repository Layer - Data access
type UserRepository struct {
db *sql.DB
}
func (r *UserRepository) FindByID(ctx context.Context, id string) (*User, error) {
// Database query implementation
}
Cette séparation facilite les tests et maintient votre code maintenable au fur et à mesure que le projet grandit.
Domain-Driven Design
Pour les applications complexes, envisagez d’organiser le code par domaine plutôt que par couches techniques. Chaque package de domaine contient ses propres modèles, services et référentiels.
Si vous construisez des applications multi-locataires (multi-tenant), comprendre les modèles de base de données pour le multi-tenancy devient crucial pour votre architecture d’API.
Gestion des Requêtes et Validation
Validation des Entrées
Validez toujours les données entrantes avant le traitement :
type CreateUserRequest struct {
Email string `json:"email" validate:"required,email"`
Username string `json:"username" validate:"required,min=3,max=50"`
Age int `json:"age" validate:"gte=0,lte=150"`
}
func (h *UserHandler) CreateUser(w http.ResponseWriter, r *http.Request) {
var req CreateUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
respondError(w, NewBadRequestError("Invalid JSON"))
return
}
validate := validator.New()
if err := validate.Struct(req); err != nil {
respondError(w, NewValidationError(err))
return
}
// Process valid request
}
Le package go-playground/validator fournit des règles de validation étendues et des validateurs personnalisés.
Contexte de la Requête
Utilisez le contexte pour les valeurs et l’annulation à portée de la requête :
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
userID, err := validateToken(token)
if err != nil {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
ctx := context.WithValue(r.Context(), "userID", userID)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
Pour une analyse approfondie des bonnes pratiques concernant le contexte — y compris les clés typées, la propagation d’annulation, les budgets de délai d’expiration et l’arrêt élégant — consultez Go context.Context Done Right.
Authentification et Sécurité
Authentification Basée sur JWT
Les JSON Web Tokens fournissent une authentification sans état :
import "github.com/golang-jwt/jwt/v5"
func generateToken(userID string) (string, error) {
claims := jwt.MapClaims{
"user_id": userID,
"exp": time.Now().Add(time.Hour * 24).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(os.Getenv("JWT_SECRET")))
}
func validateToken(tokenString string) (string, error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(os.Getenv("JWT_SECRET")), nil
})
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims["user_id"].(string), nil
}
return "", err
}
Modèles de Middleware
Implémentez les préoccupations transversales en tant que middleware :
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
log.Printf("Started %s %s", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
log.Printf("Completed in %v", time.Since(start))
})
}
func rateLimitMiddleware(next http.Handler) http.Handler {
limiter := rate.NewLimiter(10, 20) // 10 requests/sec, burst of 20
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !limiter.Allow() {
http.Error(w, "Rate limit exceeded", http.StatusTooManyRequests)
return
}
next.ServeHTTP(w, r)
})
}
Gestion des Erreurs
Implémentez des réponses d’erreur cohérentes :
type APIError struct {
Code int `json:"code"`
Message string `json:"message"`
Details string `json:"details,omitempty"`
}
func (e *APIError) Error() string {
return e.Message
}
func NewBadRequestError(message string) *APIError {
return &APIError{
Code: http.StatusBadRequest,
Message: message,
}
}
func NewNotFoundError(resource string) *APIError {
return &APIError{
Code: http.StatusNotFound,
Message: fmt.Sprintf("%s not found", resource),
}
}
func respondError(w http.ResponseWriter, err error) {
apiErr, ok := err.(*APIError)
if !ok {
apiErr = &APIError{
Code: http.StatusInternalServerError,
Message: "Internal server error",
}
// Log the actual error for debugging
log.Printf("Unexpected error: %v", err)
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(apiErr.Code)
json.NewEncoder(w).Encode(apiErr)
}
Pour un regard plus approfondi sur l’architecture des erreurs à travers les couches référentiel, service et gestionnaire — y compris les erreurs sentinelles, les types d’erreur personnalisés, la traduction des limites et le mappage sécurisé des réponses — consultez Go Error Handling Architecture: Boundaries and Patterns.
Intégration de Base de Données
Gestion des Connexions
Utilisez le pool de connexions pour un accès efficace à la base de données :
func initDB() (*sql.DB, error) {
db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
if err != nil {
return nil, err
}
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(5)
db.SetConnMaxLifetime(5 * time.Minute)
return db, db.Ping()
}
Modèles de Requête
Utilisez des instructions préparées et le contexte pour des opérations de base de données sûres :
func (r *UserRepository) FindByEmail(ctx context.Context, email string) (*User, error) {
query := `SELECT id, email, username, created_at FROM users WHERE email = $1`
var user User
err := r.db.QueryRowContext(ctx, query, email).Scan(
&user.ID,
&user.Email,
&user.Username,
&user.CreatedAt,
)
if err == sql.ErrNoRows {
return nil, ErrUserNotFound
}
return &user, err
}
Stratégies de Test
Test des Gestionnaires
Testez les gestionnaires HTTP en utilisant httptest :
func TestGetUserHandler(t *testing.T) {
// Setup
mockService := &MockUserService{
GetByIDFunc: func(ctx context.Context, id string) (*User, error) {
return &User{ID: "1", Username: "testuser"}, nil
},
}
handler := &UserHandler{service: mockService}
// Execute
req := httptest.NewRequest("GET", "/users/1", nil)
w := httptest.NewRecorder()
handler.GetUser(w, req)
// Assert
assert.Equal(t, http.StatusOK, w.Code)
var response User
json.Unmarshal(w.Body.Bytes(), &response)
assert.Equal(t, "testuser", response.Username)
}
Test d’Intégration
Testez les workflows complets avec une base de données de test :
func TestCreateUserEndToEnd(t *testing.T) {
// Setup test database
db := setupTestDB(t)
defer db.Close()
// Start test server
server := setupTestServer(db)
defer server.Close()
// Make request
body := strings.NewReader(`{"email":"test@example.com","username":"testuser"}`)
resp, err := http.Post(server.URL+"/users", "application/json", body)
require.NoError(t, err)
defer resp.Body.Close()
// Verify response
assert.Equal(t, http.StatusCreated, resp.StatusCode)
// Verify database state
var count int
db.QueryRow("SELECT COUNT(*) FROM users WHERE email = $1", "test@example.com").Scan(&count)
assert.Equal(t, 1, count)
}
Documentation de l’API
OpenAPI/Swagger
Documentez votre API en utilisant les spécifications OpenAPI :
// @title User API
// @version 1.0
// @description API for managing users
// @host localhost:8080
// @BasePath /api/v1
// @Summary Get user by ID
// @Description Retrieves a user's information by their ID
// @Tags users
// @Accept json
// @Produce json
// @Param id path string true "User ID"
// @Success 200 {object} User
// @Failure 404 {object} APIError
// @Router /users/{id} [get]
func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) {
// Implementation
}
Utilisez swaggo/swag pour générer une documentation d’API interactive à partir de ces commentaires.
Optimisation des Performances
Compression des Réponses
Activez la compression gzip pour les réponses :
import "github.com/NYTimes/gziphandler"
func main() {
r := chi.NewRouter()
r.Use(gziphandler.GzipHandler)
// Rest of setup
}
Mise en Cache
Implémentez la mise en cache pour les données fréquemment accédées :
import "github.com/go-redis/redis/v8"
type CachedUserRepository struct {
repo *UserRepository
cache *redis.Client
}
func (r *CachedUserRepository) GetByID(ctx context.Context, id string) (*User, error) {
// Try cache first
cached, err := r.cache.Get(ctx, "user:"+id).Result()
if err == nil {
var user User
json.Unmarshal([]byte(cached), &user)
return &user, nil
}
// Cache miss - fetch from database
user, err := r.repo.FindByID(ctx, id)
if err != nil {
return nil, err
}
// Store in cache
data, _ := json.Marshal(user)
r.cache.Set(ctx, "user:"+id, data, 10*time.Minute)
return user, nil
}
Pool de Connexions
Réutilisez les connexions HTTP pour les appels d’API externes :
var httpClient = &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
}
Considérations de Déploiement
Conteneurisation Docker
Créez des images Docker efficaces en utilisant des builds multi-étapes :
# Build stage
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o api ./cmd/api
# Production stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/api .
EXPOSE 8080
CMD ["./api"]
Cela produit une image minimale (généralement inférieure à 20 Mo) avec uniquement votre binaire et les certificats essentiels.
Gestion de la Configuration
Utilisez des variables d’environnement et des fichiers de configuration :
type Config struct {
Port string
DatabaseURL string
JWTSecret string
LogLevel string
}
func LoadConfig() (*Config, error) {
return &Config{
Port: getEnv("PORT", "8080"),
DatabaseURL: getEnv("DATABASE_URL", ""),
JWTSecret: getEnv("JWT_SECRET", ""),
LogLevel: getEnv("LOG_LEVEL", "info"),
}, nil
}
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
Arrêt Éléгант
Gérez correctement les signaux d’arrêt :
func main() {
server := &http.Server{
Addr: ":8080",
Handler: setupRouter(),
}
// Start server in goroutine
go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("Server error: %v", err)
}
}()
// Wait for interrupt signal
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down server...")
// Give outstanding requests 30 seconds to complete
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Fatalf("Server forced to shutdown: %v", err)
}
log.Println("Server exited")
}
Surveillance et Observabilité
Journalisation Structurée
Utilisez la journalisation structurée pour une meilleure recherche :
import "go.uber.org/zap"
func setupLogger() (*zap.Logger, error) {
config := zap.NewProductionConfig()
config.OutputPaths = []string{"stdout"}
return config.Build()
}
func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) {
logger := h.logger.With(
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.String("user_id", r.Context().Value("userID").(string)),
)
logger.Info("Processing request")
// Handler logic
}
Zap est un choix solide lorsque vous souhaitez un journalier tiers mature. Si vous préférez la bibliothèque standard, log/slog (Go 1.21+) offre des enregistrements compatibles JSON, une redaction au niveau du gestionnaire et des champs qui s’alignent avec les traces et les pipelines de journaux. Consultez Structured Logging in Go with slog for Observability and Alerting.
Collecte de Métriques
Exposez les métriques Prometheus :
import "github.com/prometheus/client_golang/prometheus"
var (
requestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "Duration of HTTP requests",
},
[]string{"method", "path", "status"},
)
)
func init() {
prometheus.MustRegister(requestDuration)
}
func metricsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
recorder := &statusRecorder{ResponseWriter: w, status: 200}
next.ServeHTTP(recorder, r)
duration := time.Since(start).Seconds()
requestDuration.WithLabelValues(
r.Method,
r.URL.Path,
strconv.Itoa(recorder.status),
).Observe(duration)
})
}
Modèles Avancés
Travail avec une Sortie Structurée
Lors de la construction d’APIs qui s’intègrent aux LLMs, vous pourriez avoir besoin de contraindre les réponses avec une sortie structurée. Ceci est particulièrement utile pour les fonctionnalités alimentées par l’IA dans votre API.
Web Scraping pour les Sources de Données d’API
Si votre API a besoin d’agrégation de données à partir d’autres sites web, comprendre les alternatives à Beautiful Soup en Go peut vous aider à implémenter une fonctionnalité de web scraping robuste.
Génération de Documents
De nombreuses APIs ont besoin de générer des documents. Pour la génération de PDF en Go, il existe plusieurs bibliothèques et approches que vous pouvez intégrer dans vos points de terminaison d’API.
Recherche Sémantique et Rééchantillonnage
Pour les APIs qui traitent la recherche et la récupération de texte, l’implémentation de rééchantillonnage avec des modèles d’embedding peut améliorer significativement la pertinence des résultats de recherche.
Construction de Serveurs MCP
Si vous implémentez des APIs qui suivent le Protocole de Contexte de Modèle, consultez ce guide sur l’implémentation de serveurs MCP en Go, qui couvre les spécifications du protocole et les implémentations pratiques.
Pièges Courants et Solutions
Mauvaise Utilisation des Contextes
Transmettez et respectez toujours le contexte tout au long de votre chaîne d’appels. Cela permet une annulation et une gestion des délais d’expiration appropriées.
Ignorer les Fuites de Goroutines
Assurez-vous que toutes les goroutines peuvent se terminer. Utilisez des contextes avec des échéances et avez toujours un moyen de signaler la complétion.
Mauvaise Gestion des Erreurs
Ne retournez pas les erreurs brutes de la base de données aux clients. Enveloppez les erreurs avec du contexte et retournez des messages assainis dans les réponses de l’API.
Validation d’Entrée Manquante
Validez toutes les entrées au point d’entrée. Ne faites jamais confiance aux données du client, même provenant d’utilisateurs authentifiés.
Tests Insuffisants
Ne testez pas seulement le scénario idéal. Couvrez les cas d’erreur, les conditions limites et les scénarios d’accès concurrent.
Résumé des Bonnes Pratiques
-
Commencez Simple : Commencez avec la bibliothèque standard. Ajoutez des frameworks lorsque la complexité l’exige.
-
Stratifiez Votre Application : Séparez les gestionnaires HTTP, la logique métier et l’accès aux données pour la maintenabilité.
-
Validez Tout : Vérifiez les entrées aux limites. Utilisez un typage fort et des bibliothèques de validation.
-
Gérez les Erreurs de Manière Cohérente : Retournez des réponses d’erreur structurées. Journalisez les erreurs internes mais ne les exposez pas.
-
Utilisez le Middleware : Implémentez les préoccupations transversales (authentification, journalisation, métriques) en tant que middleware.
-
Testez Thoroughly : Écrivez des tests unitaires pour la logique, des tests d’intégration pour l’accès aux données et des tests bout-en-bout pour les workflows.
-
Documentez Votre API : Utilisez OpenAPI/Swagger pour la documentation interactive.
-
Surveillez la Production : Implémentez la journalisation structurée, la collecte de métriques et les vérifications de santé.
-
Optimisez Prudemment : Profilez avant d’optimiser. Utilisez la mise en cache, le pool de connexions et la compression là où c’est bénéfique.
-
Concevez pour un Arrêt Éléant : Gérez les signaux de terminaison et drainez les connexions correctement.
Liste de Démarrage
Pour référence lors du travail sur des projets Go, avoir une cheat sheet Go complète à portée de main peut accélérer le développement et servir de référence rapide pour la syntaxe et les modèles communs.
Prêt à construire votre première API Go ? Commencez par ces étapes :
- ✅ Configurez votre environnement Go et la structure du projet
- ✅ Choisissez entre la bibliothèque standard ou un framework
- ✅ Implémentez des points de terminaison CRUD de base
- ✅ Ajoutez la validation des requêtes et la gestion des erreurs
- ✅ Implémentez le middleware d’authentification
- ✅ Ajoutez l’intégration de la base de données avec le pool de connexions
- ✅ Écrivez des tests unitaires et d’intégration
- ✅ Ajoutez la documentation de l’API
- ✅ Implémentez la journalisation et les métriques
- ✅ Conteneurisez avec Docker
- ✅ Configurez le pipeline CI/CD
- ✅ Déployez en production avec surveillance
Conclusion
Go fournit une excellente base pour construire des API REST, combinant performance, simplicité et des outils robustes. Que vous construisiez des microservices, des outils internes ou des API publiques, l’écosystème de Go a des solutions matures pour chaque exigence.
La clé du succès est de commencer avec des modèles architecturaux solides, d’implémenter une gestion appropriée des erreurs et de la validation dès le début, et de construire une couverture de tests complète. Au fur et à mesure que votre API grandit, les caractéristiques de performance de Go et son soutien à la concurrence vous serviront bien.
N’oubliez pas que le développement d’API est itératif. Commencez avec une implémentation minimale viable, recueillez des commentaires et affinez votre approche en fonction des modèles d’utilisation réels. La compilation rapide de Go et le refactoring straightforward rendent ce cycle d’itération fluide et productif.
Liens Utiles
- Go Cheat Sheet
- Structured Logging in Go with slog for Observability and Alerting
- Comparing Go ORMs for PostgreSQL: GORM vs Ent vs Bun vs sqlc
- Multi-Tenancy Database Patterns with examples in Go
- Beautiful Soup Alternatives for Go
- Generating PDF in GO - Libraries and examples
- Constraining LLMs with Structured Output: Ollama, Qwen3 & Python or Go
- Reranking text documents with Ollama and Qwen3 Embedding model - in Go
- Model Context Protocol (MCP), and notes on implementing MCP server in Go
Ressources Externes
Documentation Officielle
- Go Official Documentation - La documentation et les tutoriels officiels Go
- Go net/http Package - Documentation du package HTTP de la bibliothèque standard
- Effective Go - Bonnes pratiques pour écrire un code Go clair et idiomatique
Frameworks et Bibliothèques Populaires
- Gin Web Framework - Framework web HTTP rapide avec des fonctionnalités étendues
- Chi Router - Routeur léger et idiomatique pour construire des services HTTP Go
- Echo Framework - Framework web haute performance, extensible et minimaliste
- Fiber Framework - Framework web inspiré d’Express construit sur Fasthttp
- GORM - La bibliothèque ORM fantastique pour Golang
- golang-jwt - Implémentation JWT pour Go
Outils de Test et Développement
- Testify - Un ensemble d’outils avec des assertions et des mocks courants
- httptest Package - Utilitaires de la bibliothèque standard pour le test HTTP
- Swaggo - Générez automatiquement la documentation d’API RESTful
- Air - Rechargement en direct pour les applications Go pendant le développement
Bonnes Pratiques et Guides
- Go Project Layout - Structures de projet Go standard
- Uber Go Style Guide - Guide de style Go complet d’Uber
- Go Code Review Comments - Commentaires courants faits lors des revues de code Go
- REST API Design Best Practices - Principes généraux de conception d’API REST
Sécurité et Authentification
- OWASP Go Secure Coding Practices - Lignes directrices de sécurité pour les applications Go
- OAuth2 for Go - Implémentation OAuth 2.0
- bcrypt Package - Implémentation de hachage de mot de passe
Performance et Surveillance
- pprof - Outil de profilage intégré pour les programmes Go
- Prometheus Client - Bibliothèque d’instrumentation Prometheus pour Go
- Zap Logger - Journalisation rapide, structurée et nivelée
- App Architecture hub — API design, code structure, and integration patterns