- Created DeprecationInfo structure for managing deprecation metadata - Enhanced DeprecationWarning middleware with custom deprecation information support - Added standardized deprecation headers (Deprecated, Sunset, Link per RFC 8594) - Added X-API-* custom headers for compatibility - Created MarkEndpointDeprecated helper for easy endpoint deprecation - System provides clear warnings, sunset dates, and migration guidance Files modified: - veza-backend-api/internal/middleware/general.go - VEZA_COMPLETE_MVP_TODOLIST.json
109 lines
3.9 KiB
Go
109 lines
3.9 KiB
Go
package middleware
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// TTL_LEGACY_ROUTES defines the time-to-live for legacy routes before they are removed.
|
|
const TTL_LEGACY_ROUTES = 30 * 24 * time.Hour // 30 days
|
|
|
|
// DeprecationInfo contient les informations de dépréciation d'un endpoint
|
|
// INT-020: Structure pour gérer la dépréciation des endpoints
|
|
type DeprecationInfo struct {
|
|
Deprecated bool // Si l'endpoint est déprécié
|
|
SunsetDate time.Time // Date de fin de support (quand l'endpoint sera supprimé)
|
|
Replacement string // Endpoint de remplacement recommandé (ex: "/api/v1/health")
|
|
MigrationURL string // URL vers le guide de migration
|
|
Reason string // Raison de la dépréciation
|
|
}
|
|
|
|
// DeprecationWarning returns a Gin middleware that adds deprecation headers
|
|
// and logs a warning for requests to legacy routes.
|
|
// INT-020: Amélioration du middleware de dépréciation avec support de dates personnalisées
|
|
func DeprecationWarning(logger *zap.Logger) gin.HandlerFunc {
|
|
return DeprecationWarningWithInfo(logger, DeprecationInfo{
|
|
Deprecated: true,
|
|
SunsetDate: time.Now().Add(TTL_LEGACY_ROUTES),
|
|
Replacement: "/api/v1/*",
|
|
MigrationURL: "https://www.veza.app/api/v1/migration-guide",
|
|
Reason: "Legacy route - please migrate to /api/v1/* equivalent",
|
|
})
|
|
}
|
|
|
|
// DeprecationWarningWithInfo returns a Gin middleware with custom deprecation information
|
|
// INT-020: Permet de spécifier des informations de dépréciation personnalisées
|
|
func DeprecationWarningWithInfo(logger *zap.Logger, info DeprecationInfo) gin.HandlerFunc {
|
|
if !info.Deprecated {
|
|
// Si l'endpoint n'est pas déprécié, retourner un middleware no-op
|
|
return func(c *gin.Context) {
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
sunsetDateStr := info.SunsetDate.Format(time.RFC1123)
|
|
deprecationDateStr := time.Now().Format(time.RFC1123)
|
|
|
|
return func(c *gin.Context) {
|
|
// INT-020: Log un warning pour chaque accès à un endpoint déprécié
|
|
logger.Warn(
|
|
"Access to deprecated endpoint",
|
|
zap.String("method", c.Request.Method),
|
|
zap.String("path", c.Request.URL.Path),
|
|
zap.String("deprecation_date", deprecationDateStr),
|
|
zap.String("sunset_date", sunsetDateStr),
|
|
zap.String("replacement", info.Replacement),
|
|
zap.String("reason", info.Reason),
|
|
zap.String("action", fmt.Sprintf("Please migrate to %s before %s", info.Replacement, sunsetDateStr)),
|
|
)
|
|
|
|
// INT-020: Ajouter les headers de dépréciation standardisés (RFC 8594)
|
|
// Deprecated header (RFC 8594)
|
|
c.Header("Deprecated", "true")
|
|
|
|
// Sunset header (RFC 8594) - date de fin de support
|
|
c.Header("Sunset", sunsetDateStr)
|
|
|
|
// Link header pour le guide de migration
|
|
if info.MigrationURL != "" {
|
|
c.Header("Link", fmt.Sprintf("<%s>; rel=\"deprecation\"", info.MigrationURL))
|
|
}
|
|
|
|
// X-API-Deprecated header (custom, pour compatibilité)
|
|
c.Header("X-API-Deprecated", "true")
|
|
|
|
// X-API-Sunset header (custom)
|
|
c.Header("X-API-Sunset", sunsetDateStr)
|
|
|
|
// X-API-Replacement header (custom) - endpoint de remplacement
|
|
if info.Replacement != "" {
|
|
c.Header("X-API-Replacement", info.Replacement)
|
|
}
|
|
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// MarkEndpointDeprecated est un helper pour marquer un endpoint comme déprécié dans le router
|
|
// INT-020: Helper pour appliquer facilement la dépréciation aux endpoints
|
|
func MarkEndpointDeprecated(router *gin.Engine, method, path string, handler gin.HandlerFunc, logger *zap.Logger, info DeprecationInfo) {
|
|
deprecationMW := DeprecationWarningWithInfo(logger, info)
|
|
switch method {
|
|
case http.MethodGet:
|
|
router.GET(path, deprecationMW, handler)
|
|
case http.MethodPost:
|
|
router.POST(path, deprecationMW, handler)
|
|
case http.MethodPut:
|
|
router.PUT(path, deprecationMW, handler)
|
|
case http.MethodDelete:
|
|
router.DELETE(path, deprecationMW, handler)
|
|
case http.MethodPatch:
|
|
router.PATCH(path, deprecationMW, handler)
|
|
default:
|
|
router.Handle(method, path, deprecationMW, handler)
|
|
}
|
|
}
|