Golang / GoLang Production Patterns and Web Standards Interview Questions
How do you implement streaming HTTP responses in Go?
Streaming is useful when the response is large, generated incrementally, or delivered in real-time (server-sent events, file downloads). Go's http.Flusher interface allows the handler to push buffered data to the client without waiting for the full response.
// Check if ResponseWriter supports flushing func streamHandler(w http.ResponseWriter, r *http.Request) { flusher, ok := w.(http.Flusher) if !ok { http.Error(w, "streaming not supported", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") ctx := r.Context() ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() for { select { case <-ctx.Done(): return // client disconnected case t := <-ticker.C: fmt.Fprintf(w, "data: %s\n\n", t.Format(time.RFC3339)) flusher.Flush() // push to client immediately } } } // Large file download â stream without loading into memory func downloadHandler(w http.ResponseWriter, r *http.Request) { f, err := os.Open("/data/large-file.csv") if err != nil { http.Error(w, "file not found", http.StatusNotFound) return } defer f.Close() w.Header().Set("Content-Type", "text/csv") w.Header().Set("Content-Disposition", `attachment; filename="data.csv"`) // io.Copy streams from file to response in 32 KB chunks // without loading the entire file into memory if _, err := io.Copy(w, f); err != nil { log.Printf("download error: %v", err) } } // NDJSON streaming (newline-delimited JSON for large result sets) func streamResults(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/x-ndjson") enc := json.NewEncoder(w) for _, item := range largeResultSet { enc.Encode(item) // writes JSON + newline flusher.Flush() } }
More Related questions...