Skip to content

Commit bb20a42

Browse files
authored
Merge pull request #5 from lxzan/dev
Add NewStream Function
2 parents 3927c6a + 516d51f commit bb20a42

File tree

4 files changed

+175
-89
lines changed

4 files changed

+175
-89
lines changed

Diff for: README.md

+116-86
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ http request library for golang
1616
- [Features](#features)
1717
- [Install](#install)
1818
- [Usage](#usage)
19-
- [GET](#get)
20-
- [POST](#post)
21-
- [Middleware](#middleware)
19+
- [Get](#get)
20+
- [Post](#post)
21+
- [Stream](#stream)
22+
- [Error Stack](#error-stack)
23+
- [Middleware](#middleware)
2224

2325
### Features
2426

@@ -35,98 +37,126 @@ go get -v github.com/lxzan/hasaki
3537

3638
### Usage
3739

38-
##### GET
40+
#### Get
3941

40-
```go
41-
package main
42-
43-
import (
44-
"log"
45-
46-
"github.com/lxzan/hasaki"
47-
)
48-
49-
func main() {
50-
type Query struct {
51-
Q string `form:"q"`
52-
Page int `form:"page"`
53-
Order string `form:"-"`
54-
}
55-
var out = make(map[string]any)
56-
var err = hasaki.
57-
Get("https://api.github.com/search/repositories").
58-
SetQuery(Query{
59-
Q: "go-ws",
60-
Page: 1,
61-
}).
62-
Send(nil).
63-
BindJSON(out)
64-
if err != nil {
65-
log.Printf("%+v", err)
66-
}
42+
```
43+
// GET https://api.example.com/search
44+
// Send get request with path parameters
45+
46+
resp := hasaki.
47+
Get("https://api.example.com/%s", "search").
48+
Send(nil)
49+
```
50+
51+
```
52+
// GET https://api.example.com/search?q=hasaki&page=1
53+
// Send get request, with Query parameter, encoded with url.Values
54+
55+
resp := hasaki.
56+
Get("https://api.example.com/search").
57+
SetQuery(url.Values{
58+
"q": []string{"hasaki"},
59+
"page": []string{"1"},
60+
}).
61+
Send(nil)
62+
```
63+
64+
```
65+
// GET https://api.example.com/search?q=hasaki&page=1
66+
// Send get request, with Query parameter, encoded with struct
67+
68+
type Req struct {
69+
Q string `form:"q"`
70+
Page int `form:"page"`
6771
}
72+
resp := hasaki.
73+
Get("https://api.example.com/search").
74+
SetQuery(Req{
75+
Q: "hasaki",
76+
Page: 1,
77+
}).
78+
Send(nil)
79+
```
80+
81+
#### Post
6882

6983
```
84+
// POST https://api.example.com/search
85+
// Send post request, encoded with json
7086
71-
##### POST
87+
type Req struct {
88+
Q string `json:"q"`
89+
Page int `json:"page"`
90+
}
91+
resp := hasaki.
92+
Post("https://api.example.com/search").
93+
Send(Req{
94+
Q: "hasaki",
95+
Page: 1,
96+
})
97+
```
7298

73-
```go
74-
package main
75-
76-
import (
77-
"log"
78-
79-
"github.com/lxzan/hasaki"
80-
)
81-
82-
func main() {
83-
type Query struct {
84-
Q string `form:"q"`
85-
Page int `form:"page"`
86-
Order string `form:"-"`
87-
}
88-
var out = make(map[string]any)
89-
var err = hasaki.
90-
Post("https://api.github.com/search/repositories").
91-
SetEncoder(hasaki.FormEncoder).
92-
Send(Query{
93-
Q: "go-ws",
94-
Page: 1,
95-
}).
96-
BindJSON(&out)
97-
if err != nil {
98-
log.Printf("%+v", err)
99-
}
99+
```
100+
// POST https://api.example.com/search
101+
// Send post request, encoded with www-form
102+
103+
type Req struct {
104+
Q string `form:"q"`
105+
Page int `form:"page"`
100106
}
107+
resp := hasaki.
108+
Post("https://api.example.com/search").
109+
SetEncoder(hasaki.FormEncoder).
110+
Send(Req{
111+
Q: "hasaki",
112+
Page: 1,
113+
})
101114
```
102115

103-
### Middleware
116+
#### Stream
104117

105-
```go
106-
package main
107-
108-
import (
109-
"context"
110-
"log"
111-
"net/http"
112-
"time"
113-
114-
"github.com/lxzan/hasaki"
115-
)
116-
117-
func main() {
118-
before := hasaki.WithBefore(func(ctx context.Context, request *http.Request) (context.Context, error) {
119-
return context.WithValue(ctx, "t0", time.Now()), nil
120-
})
121-
122-
after := hasaki.WithAfter(func(ctx context.Context, response *http.Response) (context.Context, error) {
123-
t0 := ctx.Value("t0").(time.Time)
124-
log.Printf("latency=%s", time.Since(t0).String())
125-
return ctx, nil
126-
})
127-
128-
var url = "https://api.github.com/search/repositories"
129-
cli, _ := hasaki.NewClient(before, after)
130-
cli.Get(url).Send(nil)
118+
```
119+
// POST https://api.example.com/upload
120+
// Send a put request, using a byte stream
121+
122+
var reader io.Reader
123+
encoder := hasaki.NewStreamEncoder(hasaki.MimeSTREAM)
124+
resp := hasaki.
125+
Put("https://api.example.com/upload").
126+
SetEncoder(encoder).
127+
Send(reader)
128+
```
129+
130+
#### Error Stack
131+
132+
```
133+
// Print the error stack
134+
data := make(map[string]any)
135+
err := hasaki.
136+
Post("https://api.example.com/upload").
137+
Send(nil).
138+
BindJSON(&data)
139+
if err != nil {
140+
log.Printf("%+v", err)
131141
}
142+
```
143+
144+
#### Middleware
145+
146+
```go
147+
// Statistics on time spent on requests
148+
149+
before := hasaki.WithBefore(func (ctx context.Context, request *http.Request) (context.Context, error) {
150+
return context.WithValue(ctx, "t0", time.Now()), nil
151+
})
152+
153+
after := hasaki.WithAfter(func (ctx context.Context, response *http.Response) (context.Context, error) {
154+
t0 := ctx.Value("t0").(time.Time)
155+
log.Printf("latency=%s", time.Since(t0).String())
156+
return ctx, nil
157+
})
158+
159+
var url = "https://api.github.com/search/repositories"
160+
cli, _ := hasaki.NewClient(before, after)
161+
cli.Get(url).Send(nil)
132162
```

Diff for: encoding.go

+29
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package hasaki
33
import (
44
"bytes"
55
"io"
6+
"net/url"
67
"strings"
78

89
"github.com/valyala/bytebufferpool"
@@ -51,6 +52,9 @@ type form_encoder struct{}
5152

5253
// Encode do not support float number
5354
func (f form_encoder) Encode(v any) (io.Reader, error) {
55+
if values, ok := v.(url.Values); ok {
56+
return strings.NewReader(values.Encode()), nil
57+
}
5458
values, err := form.NewEncoder().Encode(v)
5559
if err != nil {
5660
return nil, errors.WithStack(err)
@@ -75,3 +79,28 @@ func (c *closerWrapper) Close() error {
7579
bytebufferpool.Put(c.B)
7680
return nil
7781
}
82+
83+
type streamEncoder struct {
84+
contentType string
85+
}
86+
87+
func NewStreamEncoder(contentType string) Encoder {
88+
return &streamEncoder{contentType: contentType}
89+
}
90+
91+
func (c *streamEncoder) Encode(v any) (io.Reader, error) {
92+
switch r := v.(type) {
93+
case io.Reader:
94+
return r, nil
95+
case []byte:
96+
return bytes.NewReader(r), nil
97+
case string:
98+
return strings.NewReader(r), nil
99+
default:
100+
return nil, errors.WithStack(errUnsupportedData)
101+
}
102+
}
103+
104+
func (c *streamEncoder) ContentType() string {
105+
return c.contentType
106+
}

Diff for: encoding_test.go

+26-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,38 @@
11
package hasaki
22

33
import (
4+
"bytes"
5+
"net/url"
46
"testing"
57

68
"github.com/stretchr/testify/assert"
79
)
810

911
func TestForm_encoder_Encode(t *testing.T) {
10-
_, err := FormEncoder.Encode(struct {
12+
_, err1 := FormEncoder.Encode(struct {
1113
Name string
1214
}{Name: "caster"})
13-
assert.NoError(t, err)
15+
assert.NoError(t, err1)
16+
17+
_, err2 := FormEncoder.Encode(url.Values{
18+
"name": []string{"caster"},
19+
})
20+
assert.NoError(t, err2)
21+
}
22+
23+
func TestStreamEncoder(t *testing.T) {
24+
encoder := NewStreamEncoder("text/plain")
25+
assert.Equal(t, encoder.ContentType(), "text/plain")
26+
27+
_, err1 := encoder.Encode("aha")
28+
assert.NoError(t, err1)
29+
30+
_, err2 := encoder.Encode([]byte("aha"))
31+
assert.NoError(t, err2)
32+
33+
_, err3 := encoder.Encode(bytes.NewBufferString("oh"))
34+
assert.NoError(t, err3)
35+
36+
_, err4 := encoder.Encode(123)
37+
assert.Error(t, err4)
1438
}

Diff for: request.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import (
1111
"github.com/pkg/errors"
1212
)
1313

14-
var errEmptyResponse = errors.New("unexpected empty response")
14+
var (
15+
errEmptyResponse = errors.New("unexpected empty response")
16+
errUnsupportedData = errors.New("unsupported data type")
17+
)
1518

1619
type Request struct {
1720
err error

0 commit comments

Comments
 (0)