Skip to content

Commit 581f638

Browse files
committed
feat: decode json data in response.
1 parent 1b176e7 commit 581f638

File tree

4 files changed

+85
-5
lines changed

4 files changed

+85
-5
lines changed

encoding.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package request
2+
3+
import (
4+
"encoding/json"
5+
"io"
6+
)
7+
8+
func decodeJson(body io.Reader, out any) error {
9+
return json.NewDecoder(body).Decode(out)
10+
}

request.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ func Request(url string, out any, opts ...RequestOptions) error {
2222
}
2323

2424
func (cli *Client) Request(url string, out any, opts ...RequestOptions) error {
25-
_, err := cli.RequestRaw(url, opts...)
25+
resp, err := cli.RequestRaw(url, opts...)
2626
if err != nil {
2727
return err
2828
}
2929

30-
// TODO: decode body
30+
if err := cli.decodeResponseBody(resp, out); err != nil {
31+
return err
32+
}
3133

3234
return nil
3335
}
@@ -58,9 +60,9 @@ func (cli *Client) RequestRaw(url string, opts ...RequestOptions) (*http.Respons
5860
}
5961

6062
func (cli *Client) makeRequest(url string, opt RequestOptions) (*http.Request, context.CancelFunc, error) {
61-
method := "GET"
62-
if opt.Method != "" {
63-
method = opt.Method
63+
method := opt.Method
64+
if method != "" {
65+
method = http.MethodGet
6466
}
6567

6668
url, err := cli.parseURL(url, opt)

request_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package request
2+
3+
import (
4+
"strings"
5+
"testing"
6+
)
7+
8+
type ExampleProduct struct {
9+
Id int64
10+
Category string
11+
}
12+
13+
type ExampleProductsSearchData struct {
14+
Products *[]ExampleProduct
15+
}
16+
17+
func TestSimpleRequest(t *testing.T) {
18+
var data ExampleProduct
19+
20+
err := Request("https://dummyjson.com/products/1", &data)
21+
if err != nil {
22+
t.Fatalf("Unexpected request error: %v", err)
23+
}
24+
25+
if data.Id != 1 {
26+
t.Fatalf("Expect product id is 1, actually %d", data.Id)
27+
}
28+
}
29+
30+
func TestRequestWithParameters(t *testing.T) {
31+
var data ExampleProductsSearchData
32+
33+
err := Request("https://dummyjson.com/products/search", &data, RequestOptions{
34+
Parameters: map[string][]string{
35+
"q": {"laptop"},
36+
},
37+
})
38+
if err != nil {
39+
t.Fatalf("Unexpected request error: %v", err)
40+
}
41+
42+
if data.Products != nil {
43+
for _, product := range *data.Products {
44+
if !strings.Contains(product.Category, "laptop") {
45+
t.Fatalf("Expect product category contains 'laptop', actually %s", product.Category)
46+
}
47+
}
48+
}
49+
}

response.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package request
2+
3+
import (
4+
"net/http"
5+
"strings"
6+
)
7+
8+
func (cli *Client) decodeResponseBody(resp *http.Response, out any) error {
9+
contentType := resp.Header.Get("Content-Type")
10+
contentType, _, _ = strings.Cut(contentType, ";") // remove parameters
11+
contentType = strings.TrimSpace(contentType)
12+
13+
switch contentType {
14+
case "application/json":
15+
return decodeJson(resp.Body, out)
16+
}
17+
18+
return nil
19+
}

0 commit comments

Comments
 (0)