Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

struct with json.Marshaler fail to build schema #79

Open
slow-zhang opened this issue Nov 16, 2021 · 8 comments
Open

struct with json.Marshaler fail to build schema #79

slow-zhang opened this issue Nov 16, 2021 · 8 comments

Comments

@slow-zhang
Copy link
Contributor

slow-zhang commented Nov 16, 2021

the code of https://github.com/emicklei/go-restful-openapi/ is here:
image

test struct

type Conn struct {
	URL string
}

func (v Conn) MarshalJSON() ([]byte, error) { ... }

type A struct {
	ID   int
	Conn Conn
}

open-api json struct

{
"ID": "stirng"
"Conn": "string"
}
@emicklei
Copy link
Owner

thank you reporting this. Could you help me by providing a testcase for this?

@slow-zhang
Copy link
Contributor Author

slow-zhang commented Dec 16, 2021

is there some examples for adding a test cases

@slow-zhang
Copy link
Contributor Author

slow-zhang commented Dec 16, 2021

here is the test

type Parent struct {
	FieldA string
}

func (v Parent) MarshalJSON() ([]byte, error) { return nil,nil }

type Child struct {
	FieldA Parent
	FieldB int
}

func TestParentChildArray(t *testing.T) {
	db := definitionBuilder{Definitions: spec.Definitions{}, Config: Config{}}
	db.addModelFrom(Child{})
	s := spec.Schema{
		SchemaProps: spec.SchemaProps{
			Definitions: db.Definitions,
		},
	}
	data, _ := json.MarshalIndent(s, "", "  ")
	log.Fatalln(string(data))
}

output:

{
  "definitions": {
    "restfulspec.Child": {
      "required": [
        "FieldA",
        "FieldB"
      ],
      "properties": {
        "FieldA": {
          "type": "string"
        },
        "FieldB": {
          "type": "integer",
          "format": "int32"
        }
      }
    }
  }
}

@emicklei
Copy link
Owner

thank you for the test, I will look for a solution

@slow-zhang
Copy link
Contributor Author

slow-zhang commented Nov 30, 2022 via email

@bjornbyte
Copy link

bjornbyte commented Jun 27, 2023

@emicklei have you considered simply deleting the code block checking for the custom marhalling? What is it for anyway?

Found this because I was having a similar (the same?) problem. I have a type

// ValidJSONArray represents a generic slice which, when marshalled to json, will give an empty array
// for both nil and empty slices.  This prevents a field which a client expects to be an array from being "null"
type ValidJSONArray[T any] []T

func (v ValidJSONArray[T]) MarshalJSON() ([]byte, error) {
	if v == nil {
		v = make([]T, 0)
	}
	return json.Marshal([]T(v))
}

and when I replaced my slice properties with ValidJSONArray, suddently they all had type of "string" in the open api spec!

e.g. this produces a correct spec:

type ClaimByKeysReq struct {
	Keys []string `json:"keys"`
	Regions   []string `json:"regions"`
}

but this does not

type ClaimByKeysReq struct {
	Keys ValidJSONArray[string] `json:"keys"`
	Regions   ValidJSONArray[string] `json:"regions"`
}

however, if I just delete the code block in the screenshot in the original post on this issue, it works exactly as expected.

@slow-zhang
Copy link
Contributor Author

slow-zhang commented Jun 27, 2023 via email

@emicklei
Copy link
Owner

so running the last test with code that skips checking the json Marshalling, I get:

  "definitions": {
    "restfulspec.Child": {
      "required": [
        "FieldA",
        "FieldB"
      ],
      "properties": {
        "FieldA": {
          "$ref": "#/definitions/restfulspec.Parent"
        },
        "FieldB": {
          "type": "integer",
          "format": "int32"
        }
      }
    },
    "restfulspec.Parent": {
      "required": [
        "FieldA"
      ],
      "properties": {
        "FieldA": {
          "type": "string"
        }
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants