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

introduction http

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)

πŸ“Ÿ Convert HTTP response io.ReadCloser to string in Go

Learn how to convert a HTTP client response body to string
introduction http

♾️ Infinite loop in Go

Learn how to define a "while true" loop
introduction loop

πŸ§‘β€πŸ€β€πŸ§‘ Copy a slice in Go

Learn how to make a deep copy of a slice
introduction slice