Skip to content

Commit

Permalink
feat: 使用 OmitBehaviour 来控制 json 序列化的 omitnil 行为 (#260)
Browse files Browse the repository at this point in the history
* feat: add UseEmptyNil
  • Loading branch information
sesky4 committed Mar 27, 2024
1 parent 113f244 commit 38d8978
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 41 deletions.
4 changes: 1 addition & 3 deletions README.md
Expand Up @@ -612,9 +612,7 @@ func main() {

在 >= v1.0.739 的版本, SDK使用`omitnil`标签来序列化请求, 此时nil数组会被忽略掉, 但是空数组可以被正常发送。

需要注意的是这个改动在大部分情况下对于用户是无感知的, 但是在特殊情况下依然可能会造成行为不一致。

参考[示例](https://github.com/TencentCloud/tencentcloud-sdk-go/blob/master/examples/common/omitempty.go)
在 >= v1.0.885 版本中我们对这一特性增加了开关, 当你不希望发送一个空数组时, 可以通过 `json.OmitBehaviour = json.OmitEmpty` 来关闭该特性, 参考[示例](https://github.com/TencentCloud/tencentcloud-sdk-go/blob/master/examples/common/omitempty.go)

# 支持产品列表

Expand Down
45 changes: 8 additions & 37 deletions examples/common/omitempty.go
Expand Up @@ -3,25 +3,25 @@ package main
import (
"fmt"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/regions"
trtc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/trtc/v20190722"
"os"
)

func main() {
//SDK 使用 `omitempty` 标签来序列化你的 request 对象, 因为这样可以避免上报空数组/对象.
//但对有的接口而言, 长度为0的数组 和 nil数组 是有区别的, 如果你希望在请求中携带空数组, 需要使用Common Client 来发送请求.
// SDK 使用 `omitnil` 标签来序列化你的 request 对象, 因为这样可以区分 `nil数组` 和 `长度为0的数组`

// 错误的做法
wrongWay()
// SDK 默认会发送 `长度为0的数组` 而忽略 `nil数组`
sendJsonRequest()

// 正确的做法
rightWay()
// 当你不希望发送一个 `长度为0的数组` 时, 可以通过 json.OmitBehaviour 来关闭此特性
json.OmitBehaviour = json.OmitEmpty
sendJsonRequest()
}

func wrongWay() {
func sendJsonRequest() {
credential := common.NewCredential(
os.Getenv("TENCENTCLOUD_SECRET_ID"),
os.Getenv("TENCENTCLOUD_SECRET_KEY"))
Expand All @@ -43,32 +43,3 @@ func wrongWay() {

fmt.Println(response.ToJsonString())
}

func rightWay() {
credential := common.NewCredential(
os.Getenv("TENCENTCLOUD_SECRET_ID"),
os.Getenv("TENCENTCLOUD_SECRET_KEY"))
cpf := profile.NewClientProfile()
cpf.Debug = true

client := common.NewCommonClient(credential, regions.Guangzhou, cpf)
request := tchttp.NewCommonRequest("trtc", "2019-07-22", "UpdatePublishCdnStream")
req := map[string]interface{}{
"PublishCdnParams": []*trtc.McuPublishCdnParam{},
}

// 发送的请求body为 `{"PublishCdnParams":[]}`
err := request.SetActionParameters(req)
if err != nil {
panic(err)
}

response := tchttp.NewCommonResponse()

err = client.Send(request, response)
if err != nil {
fmt.Printf("fail to invoke api: %v \n", err)
}

fmt.Println(string(response.GetBody()))
}
17 changes: 16 additions & 1 deletion tencentcloud/common/json/encode.go
Expand Up @@ -635,12 +635,27 @@ type structEncoder struct {
fieldEncs []encoderFunc
}

const (
OmitNil = 0 + iota
OmitEmpty
)

var OmitBehaviour = OmitNil

func shouldOmit(f field, fv reflect.Value) bool {
if OmitBehaviour == OmitNil {
return !fv.IsValid() || (f.omitNil || f.omitEmpty) && isNilValue(fv)
} else {
return !fv.IsValid() || (f.omitNil || f.omitEmpty) && isEmptyValue(fv)
}
}

func (se *structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
e.WriteByte('{')
first := true
for i, f := range se.fields {
fv := fieldByIndex(v, f.index)
if !fv.IsValid() || (f.omitNil || f.omitEmpty) && isNilValue(fv) {
if shouldOmit(f, fv) {
continue
}
if first {
Expand Down

0 comments on commit 38d8978

Please sign in to comment.