Skip to main content
  1. Tutorials/

πŸ“” Convert a struct to io.Reader in Go

·2 mins

To convert a struct to io.Reader in Go and send it as an HTTP POST request body, you need to encode the object to byte representation, for example, JSON. The result of the encoding should be stored in the bytes.Buffer or bytes.Reader objects which implement the io.Reader interface.

Check how to convert a byte slice to io.Reader

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "log"
    "net/http"
)

type Fruit struct {
    Name  string `json:"name"`
    Color string `json:"color"`
}

func main() {
    // encode a Fruit object to JSON and write it to a buffer
    f := Fruit{
        Name:  "Apple",
        Color: "green",
    }
    var buf bytes.Buffer
    err := json.NewEncoder(&buf).Encode(f)
    if err != nil {
        log.Fatal(err)
    }

    client := &http.Client{}
    req, err := http.NewRequest(http.MethodPost, "https://postman-echo.com/post", &buf)
    if err != nil {
        log.Fatal(err)
    }
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }

    bytes, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(string(bytes))
}

In lines 19-27, we create a new instance of the Fruit struct and encode it into JSON using json.Encoder. The result is written to a bytes.Buffer, which implements the io.Writer and io.Reader interfaces. In this way, we can use this buffer not only as an io.Writer, to which the JSON result is stored, but also as io.Reader, required when making a POST request.

Alternatively, you can encode the struct into a JSON byte slice using the json.Marshal() function and create a new bytes.Reader that is a struct for reading data from this slice which implements the required io.Reader interface.

19
20
21
22
23
24
25
26
27
28
29
30
f := Fruit{
    Name:  "Apple",
    Color: "green",
}
data, err := json.Marshal(f)
if err != nil {
    log.Fatal(err)
}
reader := bytes.NewReader(data)

client := &http.Client{}
req, err := http.NewRequest(http.MethodPost, "https://postman-echo.com/post", reader)