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

[REQ] [go] wish to optionally strict json.Unmarshall in decode() #11832

Open
iafilius opened this issue Mar 8, 2022 · 0 comments
Open

[REQ] [go] wish to optionally strict json.Unmarshall in decode() #11832

iafilius opened this issue Mar 8, 2022 · 0 comments

Comments

@iafilius
Copy link

iafilius commented Mar 8, 2022

[go] wish to optionally strict json.Unmarshall in decode()

currently when generating go code json.Unmarshall is used to map json objects into go structures.
however by default json.Unmarshall does not throw an error when a json key has no matching go strcture to map on.
As stated on

json#Unmarshal:

 By default, object keys which don't have a corresponding struct field are ignored (see Decoder.DisallowUnknownFields for an alternative).

example generated code for decode (6.0.0-SNAPSHOT):

func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) {
	if len(b) == 0 {
		return nil
	}
	if s, ok := v.(*string); ok {
		*s = string(b)
		return nil
	}
	if f, ok := v.(**os.File); ok {
		*f, err = ioutil.TempFile("", "HttpClientFile")
		if err != nil {
			return
		}
		_, err = (*f).Write(b)
		if err != nil {
			return
		}
		_, err = (*f).Seek(0, io.SeekStart)
		return
	}
	if xmlCheck.MatchString(contentType) {
		if err = xml.Unmarshal(b, v); err != nil {
			return err
		}
		return nil
	}
	if jsonCheck.MatchString(contentType) {
		if actualObj, ok := v.(interface{ GetActualInstance() interface{} }); ok { // oneOf, anyOf schemas
			if unmarshalObj, ok := actualObj.(interface{ UnmarshalJSON([]byte) error }); ok { // make sure it has UnmarshalJSON defined
				if err = unmarshalObj.UnmarshalJSON(b); err != nil {
					return err
				}
			} else {
				return errors.New("Unknown type with GetActualInstance but no unmarshalObj.UnmarshalJSON defined")
			}
		} else if err = json.Unmarshal(b, v); err != nil { // simple model
			return err
		}
		return nil
	}
	return errors.New("undefined response type")
}

In case of //simple model, reading(decoding) json structures might ignore
objects/keys are not decoded (in case of schema mismatch)

Wish to optionally generate (json) decoder with strict schema checking

I would prefer to have an early warning option to catch the case of schema/data mismatch when
reading/decoding json data, to make sure we are aware (with error)
objects/keys are going to be lost.

Currently i notice a "newstrictDecoder()" in client.go but it looks like
not be-ing used for this purpose.

I was expecting(hoping) the option "--strict-spec true" would trigger a feature
also to check the actual data to match on schema but it is "only" checking the specfile, not actual data
as it seems.
--strict-spec Feature described in #1086

Current "shortcut"

Currently put in as a hack client.go:decode to perform such check:

func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) {
        if len(b) == 0 {
                return nil
        }
        if s, ok := v.(*string); ok {
                *s = string(b)
                return nil
        }
        if f, ok := v.(**os.File); ok {
                *f, err = ioutil.TempFile("", "HttpClientFile")
                if err != nil {
                        return
                }
                _, err = (*f).Write(b)
                if err != nil {
                        return
                }
                _, err = (*f).Seek(0, io.SeekStart)
                return
        }
        if xmlCheck.MatchString(contentType) {
                if err = xml.Unmarshal(b, v); err != nil {
                        return err
                }
                return nil
        }
        if jsonCheck.MatchString(contentType) {
                if actualObj, ok := v.(interface{ GetActualInstance() interface{} }); ok { // oneOf, anyOf schemas
                        if unmarshalObj, ok := actualObj.(interface{ UnmarshalJSON([]byte) error }); ok { // make sure it has UnmarshalJSON defined
                                if err = unmarshalObj.UnmarshalJSON(b); err != nil {
                                        return err
                                }
                        } else {
                                return errors.New("Unknown type with GetActualInstance but no unmarshalObj.UnmarshalJSON defined")
                        }
                } else if err = safeJSONUnmarshalbyte(b, v); err != nil { // Hack ArFi to implement strict json map checks
                        // err = json.Unmarshal(b, v); err != nil { // simple model
                        return err
                }
                return nil
        }
        return errors.New("undefined response type")
}

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

No branches or pull requests

1 participant