Intégration de middleware existant dans Go-restful
Go-restful offre un mécanisme pour convertir les gestionnaires HTTP standard en filtres compatibles. Cette approche permet de réutiliser les middlewares existants comme l'authentfiication, la journalisation ou le suivi des performances.
Mécanisme de conversion
La fonction HttpMiddlewareHandlerToFilter transforme un http.Handler en filtre Go-restful :
// Middleware d'authentification standard
func verifierAcces(suivant http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Credential") != "valide" {
http.Error(w, "Accès refusé", http.StatusForbidden)
return
}
suivant.ServeHTTP(w, r)
})
}
// Utilisation dans Go-restful
service := new(restful.WebService)
service.Route(service.GET("/donnees").Filter(
restful.HttpMiddlewareHandlerToFilter(verifierAcces),
).To(obtenirDonnees))
Cas d'utilisation pratiques
Intégration de JWT
jwtAuth := jwt.New(jwt.Config{
CleSignature: []byte("secret"),
})
service.Route(service.GET("/protege").Filter(
restful.HttpMiddlewareHandlerToFilter(jwtAuth.Gestionnaire),
).To(handlerProtege))
Journalisation des requêtes
func trace(logger io.Writer) func(http.Handler) http.Handler {
return func(suivant http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
identifiantTrace := genererID()
w.Header().Set("x-trace-id", identifiantTrace)
suivant.ServeHTTP(w, r)
logger.Write([]byte(identifiantTrace))
})
}
}
Chaînage de filtres
service.Route(service.GET("/utilisateurs").Filter(
restful.HttpMiddlewareHandlerToFilter(traceur),
restful.HttpMiddlewareHandlerToFilter(verifierAcces),
restful.FiltreOPTIONS,
restful.FiltreCORS(),
).To(handlerUtilisateurs))
Bonnes pratiques
Concevoir des middlewares indépendants du framwork :
func LimiteurRequetes(limite int) func(http.Handler) http.Handler {
return func(suivant http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Logique de limitation
suivant.ServeHTTP(w, r)
})
}
}
Gestion des erreurs
func middlewareReprise(suivant http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
log.Printf("Erreur contrôlée: %v", err)
http.Error(w, "Erreur serveur", http.StatusInternalServerError)
}
}()
suivant.ServeHTTP(w, r)
})
}
Considérations techniques
- Privilégiez les filtres natifs pour les composants critiques
- Évitez les conversions superflues dans les chemins sensibles aux performances
- Effectuez des tests de charge pour évaluer l'impact