Skip to content

Commit

Permalink
issue OpenAPITools#11401 - Go client generator doesn't support deepOb…
Browse files Browse the repository at this point in the history
…ject in query
  • Loading branch information
parvit committed Nov 4, 2022
1 parent 06354d5 commit 0d9ff71
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 33 deletions.
10 changes: 5 additions & 5 deletions modules/openapi-generator/src/main/resources/go/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,10 @@ func (a *{{{classname}}}Service) {{nickname}}Execute(r {{#structPrefix}}{{&class
if reflect.TypeOf(t).Kind() == reflect.Slice {
s := reflect.ValueOf(t)
for i := 0; i < s.Len(); i++ {
localVarQueryParams.Add("{{baseName}}", parameterToString(s.Index(i), "{{collectionFormat}}"))
parameterToString(localVarQueryParams, "{{baseName}}", s.Index(i), "{{collectionFormat}}")
}
} else {
localVarQueryParams.Add("{{baseName}}", parameterToString(t, "{{collectionFormat}}"))
parameterToString(localVarQueryParams, "{{baseName}}", t, "{{collectionFormat}}")
}
}
{{/isCollectionFormatMulti}}
Expand All @@ -207,14 +207,14 @@ func (a *{{{classname}}}Service) {{nickname}}Execute(r {{#structPrefix}}{{&class
if reflect.TypeOf(t).Kind() == reflect.Slice {
s := reflect.ValueOf(t)
for i := 0; i < s.Len(); i++ {
localVarQueryParams.Add("{{baseName}}", parameterToString(s.Index(i), "{{collectionFormat}}"))
parameterAddToQuery(localVarQueryParams, "{{baseName}}", s.Index(i), "{{collectionFormat}}")
}
} else {
localVarQueryParams.Add("{{baseName}}", parameterToString(t, "{{collectionFormat}}"))
parameterAddToQuery(localVarQueryParams, "{{baseName}}", t, "{{collectionFormat}}")
}
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
localVarQueryParams.Add("{{baseName}}", parameterToString(*r.{{paramName}}, "{{collectionFormat}}"))
parameterAddToQuery(localVarQueryParams, "{{baseName}}", r.{{paramName}}, "{{collectionFormat}}")
{{/isCollectionFormatMulti}}
}
{{/required}}
Expand Down
63 changes: 58 additions & 5 deletions modules/openapi-generator/src/main/resources/go/client.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,9 @@ func typeCheckParameter(obj interface{}, expected string, name string) error {
return nil
}

// parameterToString convert interface{} parameters to string, using a delimiter if format is provided.
func parameterToString(obj interface{}, collectionFormat string) string {
// parameterAddToQuery adds the provided object to the url query supporting deep object specification
// the del delimiter is used to the split the value as list
func parameterAddToQuery(queryParams url.Values, keyPrefix string, obj interface{}, collectionFormat string) {
var delimiter string
switch collectionFormat {
Expand All @@ -148,12 +149,64 @@ func parameterToString(obj interface{}, collectionFormat string) string {
}

if reflect.TypeOf(obj).Kind() == reflect.Slice {
return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]")
sliceValue := strings.Split(fmt.Sprint(obj), delimiter)
if len(sliceValue) > 0 {
var ifaceValue = make([]interface{}, 0, len(sliceValue))
for v := range sliceValue {
ifaceValue = append(ifaceValue, v)
}
parameterAddSliceToQuery( queryParams, keyPrefix, ifaceValue )
}
return

} else if reflect.TypeOf(obj).Kind() == reflect.Ptr {
var param,ok = obj.(MappedNullable)
if ok {
dataMap := param.ToMap()
parameterAddMapToQuery( queryParams, keyPrefix, dataMap )
return
}

} else if t, ok := obj.(time.Time); ok {
return t.Format(time.RFC3339)
queryParams.Add( keyPrefix, t.Format(time.RFC3339) )
return
}

queryParams.Add( keyPrefix, fmt.Sprintf("%v", obj) )
}

// parameterAddMapToQuery adds the provided map to the url parameters list supporting deep object specification
func parameterAddMapToQuery(queryParams url.Values, keyPrefix string, param map[string]interface{}) {
if len(param) == 0 {
return
}
for key,value := range param {
formattedKey := fmt.Sprintf("%s[%s]", keyPrefix, key)
if reflect.TypeOf(value).Kind() == reflect.Slice {
parameterAddSliceToQuery( queryParams, formattedKey, value.([]interface{}) )
} else if reflect.TypeOf(value).Kind() == reflect.Map {
parameterAddMapToQuery( queryParams, formattedKey, value.(map[string]interface{}) )
} else {
queryParams.Add( formattedKey, fmt.Sprintf("%v", value) )
}
}
}

return fmt.Sprintf("%v", obj)
// parameterAddMapToQuery adds the provided slice to the url parameters list supporting deep object specification
func parameterAddSliceToQuery(queryParams url.Values, keyPrefix string, param []interface{}) {
if len(param) == 0 {
return
}
for index,value := range param {
formattedKey := fmt.Sprintf("%s[%d]", keyPrefix, index)
if reflect.TypeOf(value).Kind() == reflect.Slice {
parameterAddSliceToQuery( queryParams, formattedKey, value.([]interface{}) )
} else if reflect.TypeOf(value).Kind() == reflect.Map {
parameterAddMapToQuery( queryParams, formattedKey, value.(map[string]interface{}) )
} else {
queryParams.Add( formattedKey, fmt.Sprintf("%v", value) )
}
}
}

// helper for converting interface{} parameters to json strings
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// checks if the {{classname}} type satisfies the MappedNullable interface at compile time
var _ MappedNullable = &{{classname}}{}

// {{classname}} {{{description}}}{{^description}}struct for {{{classname}}}{{/description}}
type {{classname}} struct {
{{#parent}}
Expand Down Expand Up @@ -122,13 +125,8 @@ func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} {
// Deprecated
{{/deprecated}}
func (o *{{classname}}) Get{{name}}Ok() ({{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{vendorExtensions.x-go-base-type}}, bool) {
if o == nil{{#isNullable}}{{#vendorExtensions.x-golang-is-container}} || isNil(o.{{name}}){{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
{{^isFreeFormObject}}
return nil, false
{{/isFreeFormObject}}
{{#isFreeFormObject}}
return {{vendorExtensions.x-go-base-type}}{}, false
{{/isFreeFormObject}}
if o == nil{{#isNullable}}{{#vendorExtensions.x-golang-is-container}} || o.{{name}} == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
return nil, false
}
{{#isNullable}}
{{#vendorExtensions.x-golang-is-container}}
Expand Down Expand Up @@ -168,7 +166,7 @@ func (o *{{classname}}) Set{{name}}(v {{vendorExtensions.x-go-base-type}}) {
// Deprecated
{{/deprecated}}
func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} {
if o == nil{{^isNullable}} || isNil(o.{{name}}){{/isNullable}}{{#isNullable}}{{^vendorExtensions.x-golang-is-container}} || isNil(o.{{name}}.Get()){{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
if o == nil{{^isNullable}} || o.{{name}} == nil{{/isNullable}}{{#isNullable}}{{^vendorExtensions.x-golang-is-container}} || o.{{name}}.Get() == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
var ret {{vendorExtensions.x-go-base-type}}
return ret
}
Expand All @@ -194,13 +192,8 @@ func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} {
// Deprecated
{{/deprecated}}
func (o *{{classname}}) Get{{name}}Ok() ({{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{vendorExtensions.x-go-base-type}}, bool) {
if o == nil{{^isNullable}} || isNil(o.{{name}}){{/isNullable}}{{#isNullable}}{{#vendorExtensions.x-golang-is-container}} || isNil(o.{{name}}){{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
{{^isFreeFormObject}}
return nil, false
{{/isFreeFormObject}}
{{#isFreeFormObject}}
return {{vendorExtensions.x-go-base-type}}{}, false
{{/isFreeFormObject}}
if o == nil{{^isNullable}} || o.{{name}} == nil{{/isNullable}}{{#isNullable}}{{#vendorExtensions.x-golang-is-container}} || o.{{name}} == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
return nil, false
}
{{#isNullable}}
{{#vendorExtensions.x-golang-is-container}}
Expand All @@ -217,7 +210,7 @@ func (o *{{classname}}) Get{{name}}Ok() ({{^isArray}}{{^isFreeFormObject}}*{{/is

// Has{{name}} returns a boolean if a field has been set.
func (o *{{classname}}) Has{{name}}() bool {
if o != nil && {{^isNullable}}!isNil(o.{{name}}){{/isNullable}}{{#isNullable}}{{#vendorExtensions.x-golang-is-container}}isNil(o.{{name}}){{/vendorExtensions.x-golang-is-container}}{{^vendorExtensions.x-golang-is-container}}o.{{name}}.IsSet(){{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
if o != nil && {{^isNullable}}o.{{name}} != nil{{/isNullable}}{{#isNullable}}{{#vendorExtensions.x-golang-is-container}}o.{{name}} != nil{{/vendorExtensions.x-golang-is-container}}{{^vendorExtensions.x-golang-is-container}}o.{{name}}.IsSet(){{/vendorExtensions.x-golang-is-container}}{{/isNullable}} {
return true
}

Expand Down Expand Up @@ -258,6 +251,11 @@ func (o *{{classname}}) Unset{{name}}() {
{{/required}}
{{/vars}}
func (o {{classname}}) MarshalJSON() ([]byte, error) {
toSerialize := o.ToMap()
return json.Marshal(toSerialize)
}

func (o {{classname}}) ToMap() map[string]interface{} {
toSerialize := {{#isArray}}make([]interface{}, len(o.Items)){{/isArray}}{{^isArray}}map[string]interface{}{}{{/isArray}}
{{#parent}}
{{^isMap}}
Expand All @@ -284,19 +282,19 @@ func (o {{classname}}) MarshalJSON() ([]byte, error) {
{{#vendorExtensions.x-golang-is-container}}
{{! support for container fields is not ideal at this point because of lack of Nullable* types}}
if o.{{name}} != nil {
toSerialize["{{baseName}}"] = o.{{name}}
toSerialize["{{baseName}}"] = *o.{{name}}
}
{{/vendorExtensions.x-golang-is-container}}
{{^vendorExtensions.x-golang-is-container}}
if {{#required}}true{{/required}}{{^required}}o.{{name}}.IsSet(){{/required}} {
toSerialize["{{baseName}}"] = o.{{name}}.Get()
toSerialize["{{baseName}}"] = *o.{{name}}.Get()
}
{{/vendorExtensions.x-golang-is-container}}
{{/isNullable}}
{{! if argument is not nullable, don't set it if it is nil}}
{{^isNullable}}
if {{#required}}true{{/required}}{{^required}}!isNil(o.{{name}}){{/required}} {
toSerialize["{{baseName}}"] = o.{{name}}
if {{#required}}true{{/required}}{{^required}}o.{{name}} != nil{{/required}} {
toSerialize["{{baseName}}"] = *o.{{name}}
}
{{/isNullable}}
{{/vars}}
Expand All @@ -307,7 +305,7 @@ func (o {{classname}}) MarshalJSON() ([]byte, error) {
}
{{/isAdditionalPropertiesTrue}}
return json.Marshal(toSerialize)
return toSerialize
}
{{#isAdditionalPropertiesTrue}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package {{packageName}}

import (
"encoding/json"
"reflect"
"time"
)

Expand Down Expand Up @@ -331,4 +330,6 @@ func isNil(i interface{}) bool {
return reflect.ValueOf(i).IsZero()
}
return false
}
}type MappedNullable interface {
ToMap() map[string]interface{}
}

0 comments on commit 0d9ff71

Please sign in to comment.