package api import ( "encoding/json" "log" "net/http" ) // envelope is the standard API response wrapper. type envelope struct { Success bool `json:"success"` Data any `json:"data,omitempty"` Error string `json:"error,omitempty"` } // respondJSON writes a JSON success response with the given status code and data. func respondJSON(w http.ResponseWriter, status int, data any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) if err := json.NewEncoder(w).Encode(envelope{Success: true, Data: data}); err != nil { log.Printf("[api] encode response: %v", err) } } // respondError writes a JSON error response with the given status code and message. func respondError(w http.ResponseWriter, status int, msg string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) if err := json.NewEncoder(w).Encode(envelope{Success: false, Error: msg}); err != nil { log.Printf("[api] encode error response: %v", err) } } // respondNotFound writes a 404 JSON error response for the given entity type. func respondNotFound(w http.ResponseWriter, entity string) { respondError(w, http.StatusNotFound, entity+" not found") } // decodeJSON reads and decodes the request body into the given value. // Returns false and writes a 400 error response if decoding fails. func decodeJSON(w http.ResponseWriter, r *http.Request, v any) bool { if err := json.NewDecoder(r.Body).Decode(v); err != nil { respondError(w, http.StatusBadRequest, "invalid JSON: "+err.Error()) return false } return true }