JSON in GO with encoder and writer

published on 8/18/2024

If you attempt to use json.NewEncoder(w).Encode(jsonData) where jsonData is a []byte containing JSON data, you’ll encounter an error. Let’s break down what would happen:

  1. json.NewEncoder(w).Encode() expects to encode a Go data structure into JSON.
  2. You’re passing it jsonData, which is already JSON, but in the form of a []byte slice.
  3. The encoder will treat this []byte as a raw byte array and attempt to encode it into JSON.

The result would be something like this:

  1. No immediate error at compile time.
  2. At runtime, it will “succeed” in encoding, but not in the way you expect.
  3. The output will be a JSON string containing the base64-encoded version of your JSON data.

For example, if your original jsonData contained:

{ "name": "John", "age": 30 }

The output after using json.NewEncoder(w).Encode(jsonData) would be something like:

"eyJuYW1lIjogIkpvaG4iLCAiYWdlIjogMzB9"

This is because the encoder is treating the []byte as binary data and encoding it as a base64 string within a JSON string.

To demonstrate this behavior, here’s a small program:

package main

import (
    "encoding/json"
    "fmt"
    "os"
)

func main() {
    jsonData := []byte(`{"name": "John", "age": 30}`)

    fmt.Println("Original JSON:")
    fmt.Println(string(jsonData))

    fmt.Println("\nAfter incorrect encoding:")
    json.NewEncoder(os.Stdout).Encode(jsonData)
}

Output:

Original JSON:

{ "name": "John", "age": 30 }

After incorrect encoding:

"eyJuYW1lIjogIkpvaG4iLCAiYWdlIjogMzB9"

To avoid this issue:

  1. If you want to send the JSON as-is, use w.Write(jsonData).
  2. If you need to modify the data, first unmarshal it into a Go structure, modify it, then use json.NewEncoder(w).Encode() with the Go structure.

Remember, json.NewEncoder(w).Encode() is for encoding Go data structures into JSON, not for writing pre-formatted JSON data.