Gli interceptor Goa possono modificare sia le richieste in ingresso che le risposte in uscita. Questa capacità è fondamentale per implementare funzionalità trasversali come la validazione, l’arricchimento dei dati e la trasformazione.
Gli interceptor possono modificare le richieste prima che raggiungano l’endpoint del servizio:
func RequestModifier(e goa.Endpoint) goa.Endpoint {
return func(ctx context.Context, req interface{}) (interface{}, error) {
// Converti la richiesta nel tipo specifico
payload, ok := req.(*MyPayload)
if !ok {
return nil, fmt.Errorf("tipo di richiesta non valido")
}
// Modifica il payload
payload.Timestamp = time.Now()
payload.ProcessedBy = "request-modifier"
// Passa la richiesta modificata all'endpoint
return e(ctx, payload)
}
}
Validazione
Arricchimento
Trasformazione
Gli interceptor possono anche modificare le risposte prima che vengano restituite al client:
func ResponseModifier(e goa.Endpoint) goa.Endpoint {
return func(ctx context.Context, req interface{}) (interface{}, error) {
// Chiama l'endpoint originale
res, err := e(ctx, req)
if err != nil {
return nil, err
}
// Converti la risposta nel tipo specifico
result, ok := res.(*MyResult)
if !ok {
return nil, fmt.Errorf("tipo di risposta non valido")
}
// Modifica il risultato
result.ProcessedAt = time.Now()
result.Version = "1.0"
return result, nil
}
}
Arricchimento
Trasformazione
Caching
Il contesto è un meccanismo potente per passare dati attraverso la catena degli interceptor:
func ContextEnricher(e goa.Endpoint) goa.Endpoint {
return func(ctx context.Context, req interface{}) (interface{}, error) {
// Aggiungi dati al contesto
ctx = context.WithValue(ctx, "request_id", uuid.New())
ctx = context.WithValue(ctx, "timestamp", time.Now())
// Passa il contesto modificato all'endpoint
return e(ctx, req)
}
}
Do
Don’t
Gli interceptor possono essere combinati per creare catene di elaborazione complesse:
func main() {
// Crea gli interceptor
logging := LoggingInterceptor(logger)
metrics := MetricsInterceptor(metrics)
validation := ValidationInterceptor()
enrichment := EnrichmentInterceptor()
// Crea gli endpoint
endpoints := service.NewEndpoints(svc)
// Applica gli interceptor nell'ordine desiderato
endpoints.Use(logging) // Prima il logging
endpoints.Use(metrics) // Poi le metriche
endpoints.Use(validation) // Poi la validazione
endpoints.Use(enrichment) // Infine l'arricchimento
}
Logging e Metriche
Validazione
Arricchimento
Trasformazione
Gli interceptor di richiesta e risposta sono strumenti potenti per:
Usa questi pattern con attenzione e mantieni sempre in considerazione: