Stream a JSON Array with an Encoder
Encode a large result set incrementally with json.Encoder and a buffered writer instead of marshalling the whole slice at once.
Code
package main
import (
"bufio"
"encoding/json"
"fmt"
"io"
"strings"
"time"
)
type Row struct {
ID int `json:"id"`
Message string `json:"message"`
At time.Time `json:"at"`
}
func StreamJSONArray(w io.Writer, rows <-chan Row) error {
buffered := bufio.NewWriter(w)
encoder := json.NewEncoder(buffered)
encoder.SetEscapeHTML(false)
if _, err := buffered.WriteString("["); err != nil {
return err
}
first := true
for row := range rows {
if !first {
if _, err := buffered.WriteString(","); err != nil {
return err
}
}
if err := encoder.Encode(row); err != nil {
return err
}
first = false
}
if _, err := buffered.WriteString("]"); err != nil {
return err
}
return buffered.Flush()
}
func main() {
rows := make(chan Row, 3)
at := time.Date(2026, 10, 21, 9, 0, 0, 0, time.UTC)
for i := 1; i <= 3; i++ {
rows <- Row{ID: i, Message: fmt.Sprintf("row %d", i), At: at.Add(time.Duration(i) * time.Minute)}
}
close(rows)
var out strings.Builder
if err := StreamJSONArray(&out, rows); err != nil {
fmt.Println("encode:", err)
return
}
fmt.Println(out.String())
}
Report a problem with this exampleOpens a pre-filled issue on GitHub.