Skip to content

Commit

Permalink
docs: update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
xfali committed Jul 21, 2022
1 parent 52fe072 commit 16534c8
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 66 deletions.
140 changes: 92 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,103 +28,147 @@ go get github.com/xfali/restclient

### 基础配置

请参照DefaultRestClient的API说明
可以在创建默认client时对其进行配置,支持的options请参照[options](init_opts.go)的API说明

使用为
```
// restclient.New(Option1, Option2 ... OptionN), 例:
client := restclient.New(restclient.SetTimeout(10*time.Second))
```
```
//设置读写超时
func SetTimeout(timeout time.Duration)
restclient.SetTimeout(timeout time.Duration)
```
```
//配置初始转换器列表
func SetConverters(convs []Converter)
restclient.SetConverters(convs []Converter)
```
```
//配置连接池
func SetRoundTripper(tripper http.RoundTripper)
restclient.SetRoundTripper(tripper http.RoundTripper)
```
```
// 增加处理filter
func AddFilter(filters ...Filter)
restclient.AddFilter(filters ...Filter)
```
```
//配置request创建器
func SetRequestCreator(f RequestCreator)
restclient.SetRequestCreator(f RequestCreator)
```
```
// CookieJar 配置http.Client的CookieJar
restclient.CookieJar(jar http.CookieJar)
```
```
// 配置http客户端创建器
restclient.SetClientCreator(cliCreator HttpClientCreator)
```
### 连接池配置

请参照transport的API说明
请参照http.transport的API说明

## 使用

1. 使用request传递http请求参数
```
//使用默认配置
client := restclient.New()
str := ""
n, err := c.Get(&str, "https://${ADDRESS}", nil)
n, err := c.Post(&str, "https://${ADDRESS}",
restutil.Headers().WithContentType(MediaTypeJson).Build(), Entity{})
resp := &Response{}
err := client.Exchange("http://localhost:8080/test",
request.WithResult(&ret),
request.WithResponse(resp, false))
```
2. 使用request builder创建和传递http请求参数
```
err := client.Exchange("http://localhost:8080/error",
restclient.NewRequest().
MethodPost().
RequestBody(req).
Result(&resp).
Build())
```

## 扩展

使用ClientWrapper进行行为控制和扩展功能,如增加client的输入输出日志:
```cassandraql
o := restclient.New(restclient.SetTimeout(time.Second))
c := restclient.NewWrapper(o, func(ex restclient.Exchange) restclient.Exchange {
return func(result interface{}, url string, method string, params map[string]interface{}, requestBody interface{}) (i int, e error) {
t.Logf("url: %v, method: %v, params: %v, body: %v\n", url, method, params, requestBody)
n, err := ex(result, url, method, params, requestBody)
t.Logf("result %v", result)
return n, err
}
})
str := ""
n, err := c.Get(&str, "https://${ADDRESS}", nil)
使用filter.Filter进行行为控制和扩展功能,如增加client的输入输出日志:
```
client := restclient.New(restclient.AddIFilter(filter.NewLog(xlog.GetLogger(), "")))
resp := &Response{}
err := client.Exchange("http://localhost:8080/test",
request.WithResult(&ret),
request.WithResponse(resp, false))
```
可以自行实现IFilter接口,并注册到restclient扩展其功能

## 认证

### Basic Auth

```cassandraql
```
o := restclient.New(restclient.SetTimeout(time.Second))
auth := restclient.NewBasicAuth("user", "password")
c := restclient.NewBasicAuthClient(o, auth)
str := ""
_, err := c.Get(&str, "https://${ADDRESS}", nil)
auth := filter.NewBasicAuth("user", "password")
client := restclient.New(restclient.AddIFilter(auth))
resp := &Response{}
err := client.Exchange("http://localhost:8080/test",
request.WithResult(&ret),
request.WithResponse(resp, false))
//change username and password
auth.ResetCredentials(username, password)
```

### Digest Auth

```cassandraql
o := restclient.New(restclient.SetTimeout(time.Second))
auth := restclient.NewDigestAuth("user", "password")
c := restclient.NewDigestAuthClient(o, auth)
str := ""
_, err := c.Get(&str, "https://${ADDRESS}", nil)
```
auth := filter.NewDigestAuth("user", "password")
client := restclient.New(restclient.AddIFilter(auth))
resp := &Response{}
err := client.Exchange("http://localhost:8080/test",
request.WithResult(&ret),
request.WithResponse(resp, false))
//change username and password
auth.ResetCredentials(username, password)
```

### Token Auth

```cassandraql
o := New(SetTimeout(time.Second))
auth := NewAccessTokenAuth("mytoken")
c := NewAccessTokenAuthClient(o, auth)
str := ""
_, err := c.Get(&str, "http://localhost:8080/test", nil)
```
auth := filter.NewAccessTokenAuth("{TOKEN}")
client := restclient.New(restclient.AddIFilter(auth))
resp := &Response{}
err := client.Exchange("http://localhost:8080/test",
request.WithResult(&ret),
request.WithResponse(resp, false))
//change token
auth.ResetCredentials(newToken)
//change username and password
auth.ResetCredentials("{TOKEN}")
```

### 带日志client
```$xslt
c := restclient.NewLogClient(restclient.New(), restclient.NewLog(t.Logf, "test"))
str := ""
_, err := c.Get(&str, "http://${ADDRESS}", nil)
```
client := restclient.New(restclient.AddIFilter(filter.NewLog(xlog.GetLogger(), "")))
resp := &Response{}
err := client.Exchange("http://localhost:8080/test",
request.WithResult(&ret),
request.WithResponse(resp, false))
```

### 捕捉panic
```
client := restclient.New(restclient.AddIFilter(filter.NewRecovery(xlog.GetLogger())))
resp := &Response{}
err := client.Exchange("http://localhost:8080/test",
request.WithResult(&ret),
request.WithResponse(resp, false))
```

## UrlBuilder
可以使用restclient.NewUrlBuilder为url添加参数,快速构建请求路径
```
builder := restclient.NewUrlBuilder("x/:a/tt/:b?")
builder.PathVariable("a", "1")
builder.PathVariable("b", 2)
builder.QueryVariable("c", 100)
builder.QueryVariable("d", 1.1)
url := builder.Build()
```
1 change: 1 addition & 0 deletions cookie/cookie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package cookie
import (
"context"
"fmt"
"github.com/xfali/restclient/v2"
"github.com/xfali/restclient/v2/request"
"github.com/xfali/restclient/v2/restutil"
"net/http"
Expand Down
2 changes: 2 additions & 0 deletions default_restclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ type defaultRestClient struct {
pool buffer.Pool

cliCreator HttpClientCreator
jar http.CookieJar
acceptFlag AcceptFlag
respFlag ResponseBodyFlag
transport http.RoundTripper
Expand All @@ -96,6 +97,7 @@ func New(opts ...Opt) *defaultRestClient {
ret.cliCreator = ret.newClient
}
ret.client = ret.cliCreator()
ret.client.Jar = ret.jar
return ret
}

Expand Down
27 changes: 17 additions & 10 deletions init_opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,70 +23,77 @@ import (
"time"
)

// 设置读写超时
// SetTimeout 设置读写超时
func SetTimeout(timeout time.Duration) func(client *defaultRestClient) {
return func(client *defaultRestClient) {
client.timeout = timeout
}
}

// 配置初始转换器列表
// SetConverters 配置初始转换器列表
func SetConverters(convs []Converter) func(client *defaultRestClient) {
return func(client *defaultRestClient) {
client.converters = convs
}
}

// 添加初始转换器列表
// AddConverters 添加初始转换器列表
func AddConverters(convs ...Converter) func(client *defaultRestClient) {
return func(client *defaultRestClient) {
client.converters = append(client.converters, convs...)
}
}

// 配置连接池
// SetRoundTripper 配置连接池
func SetRoundTripper(tripper http.RoundTripper) func(client *defaultRestClient) {
return func(client *defaultRestClient) {
client.transport = tripper
}
}

// 配置http客户端创建器
// SetClientCreator 配置http客户端创建器
func SetClientCreator(cliCreator HttpClientCreator) func(client *defaultRestClient) {
return func(client *defaultRestClient) {
client.cliCreator = cliCreator
}
}

// 配置是否自动添加accept
// CookieJar 配置http.Client的CookieJar
func CookieJar(jar http.CookieJar) func(client *defaultRestClient) {
return func(client *defaultRestClient) {
client.jar = jar
}
}

// SetAutoAccept 配置是否自动添加accept
func SetAutoAccept(v AcceptFlag) func(client *defaultRestClient) {
return func(client *defaultRestClient) {
client.acceptFlag = v
}
}

// 配置是否自动添加accept
// SetResponseBodyFlag 配置是否自动添加accept
func SetResponseBodyFlag(v ResponseBodyFlag) func(client *defaultRestClient) {
return func(client *defaultRestClient) {
client.respFlag = v
}
}

// 配置内存池
// SetBufferPool 配置内存池
func SetBufferPool(pool buffer.Pool) func(client *defaultRestClient) {
return func(client *defaultRestClient) {
client.pool = pool
}
}

// 增加处理filter
// AddFilter 增加处理filter
func AddFilter(filters ...filter.Filter) func(client *defaultRestClient) {
return func(client *defaultRestClient) {
client.filterManager.Add(filters...)
}
}

// 增加处理filter
// AddIFilter 增加处理filter
func AddIFilter(filters ...filter.IFilter) func(client *defaultRestClient) {
return func(client *defaultRestClient) {
for _, v := range filters {
Expand Down
7 changes: 6 additions & 1 deletion restutil/urlutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,22 @@ type UrlBuilder struct {
query map[string]interface{}
}

// NewUrlBuilder URL构造器
func NewUrlBuilder(url string) *UrlBuilder {
return &UrlBuilder{
url: url,
leftDelim: ":",
}
}

func (b *UrlBuilder) WithDelim(leftDelim, rightDelim string) *UrlBuilder {
// Delims delimiters设置占位符,用于替换url的path参数
func (b *UrlBuilder) Delims(leftDelim, rightDelim string) *UrlBuilder {
b.leftDelim = leftDelim
b.rightDelim = rightDelim
return b
}

// PathVariable 增加path变量参数
func (b *UrlBuilder) PathVariable(key string, value interface{}) *UrlBuilder {
if b.path == nil {
b.path = map[string]interface{}{}
Expand All @@ -139,6 +142,7 @@ func (b *UrlBuilder) PathVariable(key string, value interface{}) *UrlBuilder {
return b
}

// QueryVariable 增加query参数
func (b *UrlBuilder) QueryVariable(key string, value interface{}) *UrlBuilder {
if b.query == nil {
b.query = map[string]interface{}{}
Expand All @@ -147,6 +151,7 @@ func (b *UrlBuilder) QueryVariable(key string, value interface{}) *UrlBuilder {
return b
}

// Build 创建url
func (b *UrlBuilder) Build() string {
buf := strings.Builder{}
if len(b.path) > 0 {
Expand Down
17 changes: 10 additions & 7 deletions test/restclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,16 +456,19 @@ func TestErrorStruct(t *testing.T) {
})

t.Run("Post", func(t *testing.T) {
ret := testStruct{
req := testStruct{
Id: 2,
Name: "test2",
Value: 1.0,
CreateTime: time.Now(),
}
resp := testStruct{}
err := client.Exchange("http://localhost:8080/error",
request.MethodPost(),
request.WithResult(&ret),
request.WithRequestBody(ret))
restclient.NewRequest().
MethodPost().
RequestBody(req).
Result(&resp).
Build())
if err == nil {
t.Fatal(err)
} else {
Expand All @@ -476,10 +479,10 @@ func TestErrorStruct(t *testing.T) {
} else {
t.Log(err.StatusCode())
}
if ret.Id != 2 {
t.Fatal("expect id 2 but get ", ret.Id)
if resp.Id != 2 {
t.Fatal("expect id 2 but get ", resp.Id)
}
t.Log(ret)
t.Log(resp)
})
}

Expand Down

0 comments on commit 16534c8

Please sign in to comment.