98 lines
2.6 KiB
Go
98 lines
2.6 KiB
Go
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()
|
|
}
|
|
}
|