Go Http

Mapping json data directly into a defined struct

 1type Book struct {
 2  Title string `json:"title"`
 3  Author string `json:"author"`
 4}
 5
 6const bookUrl = "https://api.examplebooks.com/q=\"Pat+Rothfuss\""
 7
 8func getBooks() ([]Book, error) {
 9    res, err := http.Get(url)
10    if err != nil {
11	return nil, fmt.Errorf("error creating request: %w", err)
12    }
13    defer res.Body.Close()
14
15    data, err := io.ReadAll(res.Body)
16    if err != nil  {
17    	return nil, fmt.Errorf("error reading response body: %w", err)
18    }
19
20    books := []Book{}
21
22    if err = json.Unmarshal(data, &books); err != nil {
23	return nil, err
24    }	
25
26    return books, nil
27}
...
go

If the structure of the response resource is unknown or doesn't map to a defined struct, a map[string]any can be used as a catch all.

 1const bookUrl = "https://api.examplebooks.com/q=\"Pat+Rothfuss\""
 2
 3func getBooks() ([]map[string]any, error) {
 4    // any is an alias for interface{}
 5    // var book []map[string]interface{} is the same
 6    var books []map[string]any
 7
 8    res, err := http.Get(url)
 9    if err != nil {
10	return books, fmt.Errorf("error creating request: %w", err)
11    }
12    defer res.Body.Close()
13
14    data, err := io.ReadAll(res.Body)
15    if err != nil  {
16    	return books, fmt.Errorf("error reading response body: %w", err)
17    }
18 
19    if err = json.Unmarshal(data, &books); err != nil {
20	return books, err
21    }	
22
23    return books, nil
24}
...
go

Decoders accept a io.Reader, allowing data to be streamed which is better for large data sets. The Response body is an io.Reader already.

 1type Book struct {
 2  Title string `json:"title"`
 3  Author string `json:"author"`
 4}
 5const bookUrl = "https://api.examplebooks.com/q=\"Pat+Rothfuss\""
 6
 7func getBook() (Book, error) {
 8    res, err := http.Get(url)
 9    if err != nil {
10	return Book{}, fmt.Errorf("error creating request: %w", err)
11    }
12    defer res.Body.Close()
13
14    var book Book
15    decoder := json.NewDecoder(res.Body)
16    err = decoder.Decode(&book)
17    if err != nil {
18	return Book{}, nil
19    }
20
21    return book, nil
22}
...
go