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

Help: Unable to unmarshal server reply containing a map into map[string]interface{} #63

Open
alionski opened this issue Nov 25, 2020 · 4 comments

Comments

@alionski
Copy link

Good time of the day!

I'm having an issue with unmarshalling a server reply payload into Golang's map[string]interface{}.
The server uses gqlgen and the inbuilt scalar Map! in both input and output.
The mutation input and output in the server schema:

type Mutation {
	fooMutation(input: MutationInput!): MutationPayload
}

input MutationInput {
	inputMap: Map!
}

type MutationPayload {
	outputMap: Map!
}

The structs used on the client side:

type MutationInput struct {
	InputMap map[string]interface{} `json:"inputMap"`
}

type FooMutation struct {
	MutationPayload struct {
		OutputMap map[string]interface{} `json:"outputMap"`
	} `graphql:"fooMutation(input: $mutationInput)"`
}

The mutation executes correctly and returns json of the form (got this from a Wireshark capture of the server reply):

{
    "data": {
        "fooMutation": {
            "outputMap": {
                "Date": "Tue, 24 Nov 2020 14:20:36 GMT",
                "AnotherKey": "AnotherValue"
            }
        }
    }
}

Error on the client side: struct field for "Date" doesn't exist in any of 1 places to unmarshal

I need OutputMap to be of type map[string]interface{} and not struct as the keys and the number of keys may vary. Am I doing something wrong or is it so that the library can't work with Golang maps?

I've tried executing the mutation using a plain http client with json and the mutation and unmarshalling of the payload work without a problem.

Thank you for your help,
A

@dmitshur
Copy link
Member

I think you're not doing anything wrong, the problem here is that the Map scalar is probably not directly supported by this package.

Is Map scalar a part of the GraphQL specification, or is it something custom that gqlgen created?

@alionski
Copy link
Author

Thanks for your answer!
This scalar is not part of the gql specs (only Int, Float, String, Boolean and ID) and is something that gqlgen offers as a built-in custom scalar.

I guess my option is not to use your library in this case then and instead use simple json.

@alionski
Copy link
Author

From what I saw, the json reply contains a map both when the reply is expected to be a struct and a map (as in my case). Your library only can interpret json maps as structs with tags that correspond to the json map keys. The unmarshalling fails as in my example, OutputMap map[string]interface{} json:"outputMap"` is the only stuct field with a tag (where it's neither possible no desirable to provide tags for each map key).

@sebastian-garn
Copy link

I stumbled across the same issue. The thing is the library resolves the query, gets back the json response, iterates through it and while doing that it tries to assign the json values it finds to the appropriate struct fields. This is working fine as long as you are able to define exactly what will be in the response. But in our case one of our json response fields contains a map of unknown values (map[string]interface{}). On client side reaching that point in the json response lets the library fail with an error like Failed query: struct field for \"id\" doesn't exist in any of 1 places to unmarshal.
It would have been nice by the library if it allows me to declare fields that I would like to handle on my own. So a rule could be: if data type is json.RawMessage just put the currenty json node inside that field. Or an additional struct tag could trigger this behaviour.

alexandear pushed a commit to alexandear/graphql that referenced this issue Jan 8, 2024
* Fix typo in Events section of the readme file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants