diff --git a/clientv2/client.go b/clientv2/client.go index e0aa017..1b08563 100644 --- a/clientv2/client.go +++ b/clientv2/client.go @@ -504,9 +504,10 @@ func encodeString(v reflect.Value) ([]byte, error) { } type fieldInfo struct { - name string - jsonName string - typ reflect.Type + name string + jsonName string + omitempty bool + typ reflect.Type } func prepareFields(t reflect.Type) []fieldInfo { @@ -521,16 +522,24 @@ func prepareFields(t reflect.Type) []fieldInfo { if jsonTag == "-" { continue // Skip fields explicitly marked to be ignored } + jsonName := f.Name if jsonTag != "" { parts := strings.Split(jsonTag, ",") jsonName = parts[0] // Use the name specified in the JSON tag } - fields = append(fields, fieldInfo{ + + fi := fieldInfo{ name: f.Name, jsonName: jsonName, typ: f.Type, - }) + } + + if strings.Contains(jsonTag, "omitempty") { + fi.omitempty = true + } + + fields = append(fields, fi) } return fields @@ -545,6 +554,10 @@ func encodeStruct(v reflect.Value) ([]byte, error) { continue // Skip invalid or nil pointers to avoid panics } + if field.omitempty && fieldValue.IsZero() { + continue // Skip nil fields marked with omitempty + } + encodedValue, err := encode(fieldValue) if err != nil { return nil, err diff --git a/clientv2/client_test.go b/clientv2/client_test.go index da9606b..ef58324 100644 --- a/clientv2/client_test.go +++ b/clientv2/client_test.go @@ -578,6 +578,13 @@ func TestMarshalJSON(t *testing.T) { Name string `json:"name"` Number Number `json:"number"` } + + // example with omitted fields + type Input struct { + ID string `json:"id"` + Tags []string `json:"tags,omitempty"` + } + testDate := time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC) type args struct { v any @@ -642,6 +649,37 @@ func TestMarshalJSON(t *testing.T) { }, want: []byte(`{"time":"2021-01-01T00:00:00Z"}`), }, + { + name: "marshal omitted fields", + args: args{ + v: Request{ + OperationName: "query", + Query: `query ($input: Number!) { input }`, + Variables: map[string]any{ + "input": Input{ + ID: "1", + }, + }, + }, + }, + want: []byte(`{"operationName":"query", "query":"query ($input: Number!) { input }","variables":{"input":{"id":"1"}}}`), + }, + { + name: "marshal fields", + args: args{ + v: Request{ + OperationName: "query", + Query: `query ($input: Number!) { input }`, + Variables: map[string]any{ + "input": Input{ + ID: "1", + Tags: []string{"tag1", "tag2"}, + }, + }, + }, + }, + want: []byte(`{"operationName":"query", "query":"query ($input: Number!) { input }","variables":{"input":{"id":"1", "tags":["tag1","tag2"]}}}`), + }, { name: "marshal time.Time", args: args{