package middleware import ( "strings" "github.com/gin-gonic/gin" "go.uber.org/zap" apperrors "veza-backend-api/internal/errors" "veza-backend-api/internal/response" ) // 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 { appErr := apperrors.NewValidationError("API version mismatch") appErr.Context = map[string]interface{}{"required_version": requiredVersion, "provided_version": currentVersion} response.RespondWithAppError(c, appErr) c.Abort() return } c.Next() } }