Skip to content

Commit

Permalink
Not ignore empty (#269)
Browse files Browse the repository at this point in the history
* up issue #267

* 修改测试代码

* 更新版本号
  • Loading branch information
guonaihong authored Jan 29, 2021
1 parent 1540c8e commit 4ed376a
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 23 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [2019-2020] [guonaihong]
Copyright [2019-2021] [guonaihong]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ gout 是go写的http 客户端,为提高工作效率而开发
- [export](#export)
- [generate curl command](#generate-curl-command)
- [Incoming custom * http.Client](#Incoming-custom-*http.Client)
- [Global configuration](#Global-configuration)
- [Null values are also serialized](#Null-values-are-also-serialized)
- [Unique features](#Unique-features)
- [forward gin data](#forward-gin-data)

Expand Down Expand Up @@ -1567,6 +1569,42 @@ func main() {
}
```
# Global configuration
## Null values are also serialized
```go
query := gout.H{
"t": 1296,
"callback": "searchresult",
"q": "美食",
"stype": 1,
"pagesize": 100,
"pagenum": 1,
"imageType": 2,
"imageColor": "",
"brand": "",
"imageSType": "",
"fr": 1,
"sortFlag": 1,
"imageUType": "",
"btype": "",
"authid": "",
"_": 1611822443760,
}
```


调用代码如下:
```go
gout.GET(url).Debug(true).SetQuery(query).SetHeader(header).BindBody(&body).Do()
```

控制台请求信息如下:
```console
> GET xxxx?_=1611822443760&callback=searchresult&fr=1&imageType=2&pagenum=1&pagesize=100&q=%E7%BE%8E%E9%A3%9F&sortFlag=1&stype=1&t=1296 HTTP/1.1
```
默认会删除,```authid```等空值,使用gout.NotIgnoreEmpty()接口,空value不会删除


# Unique features
## forward gin data
gout 设计之初就考虑到要和gin协同工作的可能性,下面展示如何方便地使用gout转发gin绑定的数据。
Expand Down
2 changes: 1 addition & 1 deletion dataflow/dataflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ func (df *DataFlow) Debug(d ...interface{}) *DataFlow {
// SetWWWForm "Content-Type", "application/x-www-form-urlencoded"
// SetJSON "Content-Type", "application/json"
func (df *DataFlow) NoAutoContentType() *DataFlow {
df.Req.noAutoContentType = true
df.Req.NoAutoContentType = true
return df
}

Expand Down
8 changes: 8 additions & 0 deletions dataflow/global_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dataflow

import (
"github.com/guonaihong/gout/setting"
)

// 存放全局配置选项
var GlobalSetting setting.Setting
17 changes: 9 additions & 8 deletions dataflow/req.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/guonaihong/gout/decode"
"github.com/guonaihong/gout/encode"
api "github.com/guonaihong/gout/interface"
"github.com/guonaihong/gout/setting"
"io"
"io/ioutil"
"net/http"
Expand Down Expand Up @@ -60,9 +61,9 @@ type Req struct {
c context.Context
Err error

reqModify []api.RequestMiddler
req *http.Request
noAutoContentType bool
reqModify []api.RequestMiddler
req *http.Request
setting.Setting
}

// Reset 重置 Req结构体
Expand All @@ -72,7 +73,7 @@ type Req struct {
// 有没有必要,归一化成一种??? TODO:
func (r *Req) Reset() {
r.index = 0
r.noAutoContentType = false
r.NoAutoContentType = false
r.Err = nil
r.cookies = nil
r.form = nil
Expand Down Expand Up @@ -186,7 +187,7 @@ func (r *Req) selectRequest(body *bytes.Buffer) (req *http.Request, err error) {

func (r *Req) encodeQuery() error {
var query string
q := encode.NewQueryEncode(nil)
q := encode.NewQueryEncode(nil, r.Setting)

for _, queryEncode := range r.queryEncode {
if qStr, ok := isAndGetString(queryEncode); ok {
Expand Down Expand Up @@ -229,7 +230,7 @@ func (r *Req) encodeForm(body *bytes.Buffer, f *encode.FormEncode) error {
}

func (r *Req) encodeWWWForm(body *bytes.Buffer) error {
enc := encode.NewWWWFormEncode()
enc := encode.NewWWWFormEncode(r.Setting)
for _, formData := range r.wwwForm {
if err := enc.Encode(formData); err != nil {
return err
Expand Down Expand Up @@ -313,7 +314,7 @@ func (r *Req) Request() (req *http.Request, err error) {
}

r.addDefDebug()
if !r.noAutoContentType {
if !r.NoAutoContentType {
r.addContextType(req)
}
//运行请求中间件
Expand Down Expand Up @@ -497,5 +498,5 @@ func modifyURL(url string) string {
}

func reqDef(method string, url string, g *Gout) Req {
return Req{method: method, url: modifyURL(url), g: g}
return Req{method: method, url: modifyURL(url), g: g, Setting: GlobalSetting}
}
8 changes: 5 additions & 3 deletions encode/query.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package encode

import (
"github.com/guonaihong/gout/setting"
"net/http"
"net/url"
"reflect"
Expand All @@ -12,17 +13,18 @@ var _ Adder = (*QueryEncode)(nil)
type QueryEncode struct {
values url.Values
r *http.Request
setting.Setting
}

// NewQueryEncode create a new URL query encoder
func NewQueryEncode(req *http.Request) *QueryEncode {
return &QueryEncode{values: make(url.Values)}
func NewQueryEncode(req *http.Request, s setting.Setting) *QueryEncode {
return &QueryEncode{values: make(url.Values), Setting: s}
}

// Add Encoder core function, used to set each key / value into the http URL query
func (q *QueryEncode) Add(key string, v reflect.Value, sf reflect.StructField) error {
val := valToStr(v, sf)
if len(val) == 0 {
if !q.NotIgnoreEmpty && len(val) == 0 {
return nil
}
q.values.Add(key, val)
Expand Down
7 changes: 4 additions & 3 deletions encode/query_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package encode

import (
"github.com/guonaihong/gout/setting"
"github.com/stretchr/testify/assert"
"net/http"
"strconv"
Expand All @@ -11,7 +12,7 @@ import (
func TestQueryStringSlice(t *testing.T) {
req, _ := http.NewRequest("GET", "/", nil)

q := NewQueryEncode(req)
q := NewQueryEncode(req, setting.Setting{})

err := Encode([]string{"q1", "v1", "q2", "v2", "q3", "v3"}, q)

Expand All @@ -23,7 +24,7 @@ func TestQueryStringSlice(t *testing.T) {
func TestQueryMap(t *testing.T) {
req, _ := http.NewRequest("GET", "/", nil)

q := NewQueryEncode(req)
q := NewQueryEncode(req, setting.Setting{})

err := Encode(testH{"q1": "v1", "q2": "v2", "q3": "v3"}, q)

Expand All @@ -43,7 +44,7 @@ type testQuery struct {
func TestQueryStruct(t *testing.T) {
req, _ := http.NewRequest("GET", "/", nil)

q := NewQueryEncode(req)
q := NewQueryEncode(req, setting.Setting{})

unixTime := time.Date(2019, 07, 27, 20, 42, 53, 0, time.Local)
unixNano := time.Date(2019, 07, 27, 20, 42, 53, 1000, time.Local)
Expand Down
8 changes: 5 additions & 3 deletions encode/www_form.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package encode

import (
"github.com/guonaihong/gout/core"
"github.com/guonaihong/gout/setting"
"io"
"net/url"
"reflect"
Expand All @@ -12,12 +13,13 @@ var _ Adder = (*WWWFormEncode)(nil)
// WWWFormEncode x-www-form-urlencoded encoder structure
type WWWFormEncode struct {
values url.Values
setting.Setting
}

// NewWWWFormEncode create a new x-www-form-urlencoded encoder
func NewWWWFormEncode() *WWWFormEncode {
func NewWWWFormEncode(s setting.Setting) *WWWFormEncode {

return &WWWFormEncode{values: make(url.Values)}
return &WWWFormEncode{values: make(url.Values), Setting: s}
}

// Encode x-www-form-urlencoded encoder
Expand All @@ -31,7 +33,7 @@ func (we *WWWFormEncode) Encode(obj interface{}) (err error) {
// reflect.StructField主要是可以在Add函数里面获取tag相关信息
func (we *WWWFormEncode) Add(key string, v reflect.Value, sf reflect.StructField) error {
val := valToStr(v, sf)
if len(val) == 0 {
if !we.NotIgnoreEmpty && len(val) == 0 {
return nil
}
we.values.Add(key, val)
Expand Down
7 changes: 4 additions & 3 deletions encode/www_form_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package encode
import (
"bytes"
"github.com/guonaihong/gout/core"
"github.com/guonaihong/gout/setting"
"github.com/stretchr/testify/assert"
"testing"
)
Expand All @@ -17,8 +18,8 @@ func Test_WWWForm_Encode(t *testing.T) {
var out bytes.Buffer

tests := []testWWWForm{
{NewWWWFormEncode(), core.A{"k1", "v1", "k2", 2, "k3", 3.14}, "k1=v1&k2=2&k3=3.14"},
{NewWWWFormEncode(), core.H{"k1": "v1", "k2": 2, "k3": 3.14}, "k1=v1&k2=2&k3=3.14"},
{NewWWWFormEncode(setting.Setting{}), core.A{"k1", "v1", "k2", 2, "k3", 3.14}, "k1=v1&k2=2&k3=3.14"},
{NewWWWFormEncode(setting.Setting{}), core.H{"k1": "v1", "k2": 2, "k3": 3.14}, "k1=v1&k2=2&k3=3.14"},
}

for _, v := range tests {
Expand All @@ -31,5 +32,5 @@ func Test_WWWForm_Encode(t *testing.T) {
}

func Test_WWWForm_Name(t *testing.T) {
assert.Equal(t, NewWWWFormEncode().Name(), "www-form")
assert.Equal(t, NewWWWFormEncode(setting.Setting{}).Name(), "www-form")
}
10 changes: 10 additions & 0 deletions gout.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,13 @@ func HEAD(url string) *dataflow.DataFlow {
func OPTIONS(url string) *dataflow.DataFlow {
return dataflow.OPTIONS(url)
}

// 设置不忽略空值
func NotIgnoreEmpty() {
dataflow.GlobalSetting.NotIgnoreEmpty = true
}

// 设置忽略空值
func IgnoreEmpty() {
dataflow.GlobalSetting.NotIgnoreEmpty = false
}
65 changes: 65 additions & 0 deletions query_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package gout

import (
"bytes"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"

"github.com/guonaihong/gout/dataflow"
)

func TestQuery_NotIgnoreEmpty(t *testing.T) {

total := int32(0)
router := setupMethod(&total)

ts := httptest.NewServer(http.HandlerFunc(router.ServeHTTP))
defer ts.Close()

query := H{
"t": 1296,
"callback": "searchresult",
"q": "美食",
"stype": 1,
"pagesize": 100,
"pagenum": 1,
"imageType": 2,
"imageColor": "",
"brand": "",
"imageSType": "",
"fr": 1,
"sortFlag": 1,
"imageUType": "",
"btype": "",
"authid": "",
"_": int64(1611822443760),
}

var out bytes.Buffer
SaveDebug := func() dataflow.DebugOpt {
return DebugFunc(func(o *DebugOption) {
o.Write = &out
o.Debug = true
})
}

// 默认忽略空值
err := GET(ts.URL).Debug(SaveDebug()).SetQuery(query).Do()
assert.NoError(t, err)
// 没有authid字段
assert.Equal(t, bytes.Index(out.Bytes(), []byte("authid")), -1)

// 重置bytes.Buffer
out.Reset()
NotIgnoreEmpty()

err = GET(ts.URL).Debug(SaveDebug()).SetQuery(query).Do()
assert.NoError(t, err)
// 有authid字段
assert.NotEqual(t, bytes.Index(out.Bytes(), []byte("authid")), -1)

IgnoreEmpty()
}
8 changes: 8 additions & 0 deletions setting/setting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package setting

// 设置
type Setting struct {
NotIgnoreEmpty bool //控制是否使用空值

NoAutoContentType bool
}
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package gout

// Version show version
const Version = "v0.1.4"
const Version = "v0.1.5"

0 comments on commit 4ed376a

Please sign in to comment.