openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[BUG][Go][Bounty] Go client generator doesn't support deepObject in query

Open kamilsk opened this issue 3 years ago • 9 comments

Bug Report Checklist

  • [x] Have you provided a full/minimal spec to reproduce the issue?
  • [x] Have you validated the input using an OpenAPI validator (example)?
  • [x] Have you tested with the latest master to confirm the issue still exists?
  • [x] Have you searched for related issues/PRs?
  • [x] What's the actual output vs expected output?
  • [ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

Go client generator doesn't support deepObject in query.

openapi-generator version

v5.3.1

OpenAPI declaration file content or url
openapi: 3.0.0

info:
  title: Example
  description: Example of deepObject failure.
  version: 1.0.0

paths:
  /test:
    get:
      operationId: test
      parameters:
        - name: filter
          in: query
          style: deepObject
          explode: true
          schema:
            type: object
            properties:
              search:
                description: Filter.
                type: string
      responses:
        '200':
          description: Response.
Generation Details
$ docker run --rm -it \
    -v "$(pwd)"/api.yaml:/specs/api.yaml \
    openapitools/openapi-generator-cli:v5.3.1 generate -i /specs/api.yaml -g go -o /sdk/go
Steps to reproduce
  1. store example in api.yaml
  2. run example from "generation details"

expected result: exit code 0 and successful generated content

actual result:

  Exception: null
        at org.openapitools.codegen.DefaultGenerator.processOperation(DefaultGenerator.java:1175)
        at org.openapitools.codegen.DefaultGenerator.processPaths(DefaultGenerator.java:1066)
        at org.openapitools.codegen.DefaultGenerator.generateApis(DefaultGenerator.java:566)
        at org.openapitools.codegen.DefaultGenerator.generate(DefaultGenerator.java:907)
        at org.openapitools.codegen.cmd.Generate.execute(Generate.java:441)
        at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32)
        at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66)
Caused by: java.lang.NullPointerException
Related issues/PRs
Suggest a fix

kamilsk avatar Jan 25 '22 20:01 kamilsk

Same with v5.4.0 and latest.

gfyrag avatar May 06 '22 19:05 gfyrag

I meet the similar problem in the path parameters. I guess it is because of this line CodegenProperty property = fromProperty(entry.getKey(), entry.getValue(), requiredVarNames.contains(entry.getKey())); property.baseName = codegenParameter.baseName + "[" + entry.getKey() + "]"; return property; in DefaultCodegen Class. It updates the key property.baseName in the schemaCodegenPropertyCache map.

Christina0114 avatar Sep 14 '22 21:09 Christina0114

Similar issue on our end, we just added a $250 bounty on this one: https://app.bountysource.com/issues/112016967-bug-go-go-client-generator-doesn-t-support-deepobject-in-query

altitude avatar Oct 04 '22 11:10 altitude

The given example works fine with 6.2.0. Do you have another example which does not work?

KN4CK3R avatar Oct 04 '22 18:10 KN4CK3R

I will check it and maybe will find another example. Thanks for the comment.

kamilsk avatar Oct 05 '22 06:10 kamilsk

test result

version result
v5.3.1 failure
v5.4.0 failure
v6.0.0 success

Output is valid

...
	if r.filter != nil {
		localVarQueryParams.Add("filter", parameterToString(*r.filter, ""))
	}
...


// TestFilterParameter struct for TestFilterParameter
type TestFilterParameter struct {
	// Filter.
	Search *string `json:"search,omitempty"`
}

but logic is wrong

func parameterToString(obj interface{}, collectionFormat string) string {
	var delimiter string

	switch collectionFormat {
	case "pipes":
		delimiter = "|"
	case "ssv":
		delimiter = " "
	case "tsv":
		delimiter = "\t"
	case "csv":
		delimiter = ","
	}

	if reflect.TypeOf(obj).Kind() == reflect.Slice {
		return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]")
	} else if t, ok := obj.(time.Time); ok {
		return t.Format(time.RFC3339)
	}

	return fmt.Sprintf("%v", obj)
}

it makes an API call with something like this "/test?filter=%7B0x14000098dc0%7D", because TestFilterParameter implements only json.Marshaler and doesn't implement Stringer/GoStringer

package main

import "fmt"

type TestFilterParameter struct {
	// Filter.
	Search *string `json:"search,omitempty"`
}

func (t TestFilterParameter) GoString() string {
	return "yop"
}

func (t TestFilterParameter) String() string {
	return "yep"
}

func main() {
	s := "query"
	obj := TestFilterParameter{&s}
	fmt.Printf("%v\n", obj)
	fmt.Printf("%#v\n", obj)
}

kamilsk avatar Oct 05 '22 08:10 kamilsk

Full example

package main

import (
	"context"
	"fmt"
	"testme/openapi"
)

type TestFilterParameter struct {
	// Filter.
	Search *string `json:"search,omitempty"`
}

func (t TestFilterParameter) GoString() string {
	return "yop"
}

func (t TestFilterParameter) String() string {
	return "yep"
}

func main() {
	q := "query"
	obj := TestFilterParameter{&q}
	fmt.Printf("%v\n", obj)
	fmt.Printf("%#v\n", obj)

	ctx := context.Background()
	cl := openapi.NewAPIClient(openapi.NewConfiguration())

	req := cl.DefaultApi.Test(ctx)
	req = req.Filter(openapi.TestFilterParameter{Search: &q})

	resp, err := cl.DefaultApi.TestExecute(req)
	fmt.Println(resp, err)
}

Expected call /test?filter[search]=query, not /test?filter=%7B0x14000098dc0%7D

kamilsk avatar Oct 05 '22 08:10 kamilsk

Hi all, i've created a PR for this feature, please review it.

parvit avatar Oct 08 '22 09:10 parvit

Any feedback on this?

parvit avatar Oct 11 '22 21:10 parvit

is this issue still open?

exitflynn avatar Oct 30 '22 21:10 exitflynn

It should just be merged and closed.

Il Dom 30 Ott 2022, 22:11 Akshit Tyagi @.***> ha scritto:

is this issue still open?

— Reply to this email directly, view it on GitHub https://github.com/OpenAPITools/openapi-generator/issues/11401#issuecomment-1296351903, or unsubscribe https://github.com/notifications/unsubscribe-auth/AWGJD4BJE3DYW4EJFNITLILWF3P75ANCNFSM5MZI7K2A . You are receiving this because you commented.Message ID: @.***>

parvit avatar Oct 30 '22 21:10 parvit

@kamilsk @altitude Are you going to approve the completion of the bounty then? Seems unfair that i've completed the work and the ticket gets closed without merging.

parvit avatar Oct 31 '22 06:10 parvit

@parvit I know nothing about the bounty. I closed it because I no longer wait for it and use a different stack. Feel free to reopen the issue, but I will unsubscribe from it.

kamilsk avatar Oct 31 '22 07:10 kamilsk

Fixed via https://github.com/OpenAPITools/openapi-generator/pull/13909. Thanks @parvit for the PR.

@altitude Can you please pull the latest master to give it a try and send @parvit the bug bounty if the fix is good? Thanks.

wing328 avatar Nov 20 '22 07:11 wing328

@wing328 Is the code on the latest docker image?

gfyrag avatar Nov 21 '22 09:11 gfyrag

@wing328 Tested today with the latest image (built 16 hours ago), and same results on my end.

gfyrag avatar Nov 24 '22 09:11 gfyrag

do you mind sharing the spec so that we can use it to reproduce the issue?

wing328 avatar Nov 29 '22 07:11 wing328

@wing328 Retested from scratch with latest image, and it works as expected. Don't know why it was failing few days ago. Maybe a problem between the keyboard and the chair.

gfyrag avatar Nov 29 '22 14:11 gfyrag