📦 1. JSON Encoding & Decoding in Go
Ăśber Struct-Tags steuerst du exakt, wie Go-Structs in JSON-Felder ĂĽbersetzt werden. FĂĽr HTTP-APIs ist json.NewDecoder(r.Body).Decode(&payload) besonders speichereffizient:
type Product struct {
ID int `json:"id"`
Title string `json:"title"`
Price float64 `json:"price,omitempty"` // omitempty: lässt Feld bei 0/leer weg
SKU string `json:"-"` // '-': wird niemals in JSON exportiert
}
// 🎯 JSON-Response senden:
func GetProductHandler(w http.ResponseWriter, r *http.Request) {
p := Product{ID: 1, Title: "Cloud Server Pro", Price: 49.99}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(p)
}
🛡️ 2. Das Middleware-Pattern (Onion Architecture)
Eine Middleware ist ein Decorator-Wrapper um einen http.Handler. Sie kann Vor- und Nachbereitungen ausfĂĽhren (z.B. Authentifizierung, Performance-Messung oder Panic-Recovery):
│
â–Ľ
[1. Recovery Middleware] ─── (Fängt Panics ab und liefert 500)
│
â–Ľ
[2. Auth Middleware] ─── (Prüft Header X-API-Key oder 401)
│
â–Ľ
[3. Core Business Handler] ── (Erstellt JSON Response: 200 OK)
// Standard Middleware-Signatur:
func AuthMiddleware(secretKey string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
apiKey := r.Header.Get("X-API-Key")
if apiKey != secretKey {
http.Error(w, `{"error":"unauthorized"}`, http.StatusUnauthorized)
return
}
// Weiterreichen an den nächsten Handler
next.ServeHTTP(w, r)
})
}
}
Stell dir einen Besuch im Hochsicherheits-Rechenzentrum vor: Zuerst passierst du die Sicherheitsschleuse (Auth-Middleware) – ohne gültigen Ausweis wirst du abgewiesen. Dahinter registriert ein Sicherheitsteam deinen Zutritt im Logbuch (Logging-Middleware). Erst wenn alle Schleusen passiert sind, betrittst du den Serverraum (Business-Handler).
đź“‘ 3. Cheat-Sheet: JSON & Middleware Best Practices
| Aufgabe | Idiomatischer Go-Code | Vorteil |
|---|---|---|
| Header setzen | w.Header().Set("Content-Type", "application/json") |
Muss vor WriteHeader aufgerufen werden! |
| Streaming Decode | json.NewDecoder(r.Body).Decode(&data) |
Liest Request-Body direkt ohne extra Buffer-Kopie |
| Panic Recovery | defer func() { if err := recover(); err != nil ... }() |
Verhindert, dass eine Panic den gesamten Server crasht |
| Middleware-Chain | ApplyMiddleware(handler, mw1, mw2) |
Modulare, wiederverwendbare Filter-Pipeline |
đź§ Diagnostischer Selbst-Check
Überprüfe dein Verständnis der Kernkonzepte und typischen Go-Fallen, bevor du die Übung in der Web-IDE bearbeitest.
🎯 Aufgaben & Checkliste in aufgabe.go
In Produktions-APIs solltest du die Größe des Request-Bodys mit http.MaxBytesReader(w, r.Body, 1048576) (1 MB) begrenzen, um Denial-of-Service Angriffe durch riesige Payloads zu verhindern.