veza/veza-backend-api/internal/middleware/versioning.go
2025-12-03 20:29:37 +01:00

97 lines
2.4 KiB
Go

package middleware
import (
"strings"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// Versioning middleware pour gérer le versioning de l'API
type Versioning struct {
defaultVersion string
supportedVersions []string
logger *zap.Logger
}
// NewVersioning crée un nouveau middleware de versioning
func NewVersioning(defaultVersion string) *Versioning {
return &Versioning{
defaultVersion: defaultVersion,
supportedVersions: []string{"v1", "v2"},
logger: zap.L(),
}
}
// Handle vérifie et extrait la version de l'API depuis l'URL
func (v *Versioning) Handle() gin.HandlerFunc {
return func(c *gin.Context) {
path := c.Request.URL.Path
// Extraire la version depuis /api/v1/ ou /api/v2/
parts := strings.Split(path, "/")
if len(parts) > 2 && parts[1] == "api" {
version := parts[2]
// Valider que la version est supportée
if !v.isVersionSupported(version) {
// Utiliser la version par défaut
c.Set("api_version", v.defaultVersion)
c.Header("X-API-Version", v.defaultVersion)
// Ajouter un header de dépréciation si nécessaire
if version != "" && version != v.defaultVersion {
c.Header("X-API-Deprecated", "true")
c.Header("X-API-Supported-Versions", strings.Join(v.supportedVersions, ", "))
}
} else {
c.Set("api_version", version)
c.Header("X-API-Version", version)
}
} else {
// Pas de version dans l'URL, utiliser la valeur par défaut
c.Set("api_version", v.defaultVersion)
c.Header("X-API-Version", v.defaultVersion)
}
c.Next()
}
}
// isVersionSupported vérifie si une version est supportée
func (v *Versioning) isVersionSupported(version string) bool {
for _, supported := range v.supportedVersions {
if version == supported {
return true
}
}
return false
}
// GetVersion récupère la version de l'API depuis le contexte
func GetVersion(c *gin.Context) string {
version, exists := c.Get("api_version")
if !exists {
return "v1"
}
return version.(string)
}
// RequireVersion vérifie que la version spécifiée est utilisée
func (v *Versioning) RequireVersion(requiredVersion string) gin.HandlerFunc {
return func(c *gin.Context) {
currentVersion := GetVersion(c)
if currentVersion != requiredVersion {
c.JSON(400, gin.H{
"error": "API version mismatch",
"required_version": requiredVersion,
"provided_version": currentVersion,
})
c.Abort()
return
}
c.Next()
}
}