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

Resolver is not extracting nested structs #610

Open
Moranilt opened this issue Aug 13, 2021 · 11 comments
Open

Resolver is not extracting nested structs #610

Moranilt opened this issue Aug 13, 2021 · 11 comments

Comments

@Moranilt
Copy link

I'm using last version of graphql v0.7.9

I have query "users" which should return a list of users:

image

QueryType:
image

structs:
image

pgsql is *sqlx.DB

As you can see I'm using nested struct UserInput for UserType. Actually sqlx is binding values to it correctly and when I'm calling fmt.Println(user[0].First_name) it works good, but for graphql - not!

image

When I'm not using nested structs - it works good.
Seems like a bug.

@asif-mahmud
Copy link

i can confirm this too. i used something like this and it didnt work -

type Model struct {
    ID int64
    CreatedAt time.Time
    UpdatedAt time.Time
}
type User struct {
    Model
    Name string
    Email string
}

So when i returned a User value, the graphql parser didn't parse the fields from Model.

@bhoriuchi
Copy link
Contributor

try converting your user array to an []map[string]interface{} and see if that resolves it. The field selection might be having a hard time with custom structs?

@Moranilt
Copy link
Author

Moranilt commented Sep 5, 2021

@bhoriuchi but why should I use untyped interface? When the laguage says that I should use structs to avoid errors. It's bad idea to use []map[string]interface{}.

@bhoriuchi
Copy link
Contributor

bhoriuchi commented Sep 5, 2021

I said try it. It doesn't mean that should be your final solution but it may help figure out where the issue is.

The reason I suggest converting it is because your struct fields are capitalized and your selections are not, so how is the query expected to select the right field when the field names are not matching? Using the json.Marshal function your json tags will be respected and likely map properly.

@asif-mahmud
Copy link

asif-mahmud commented Sep 5, 2021 via email

@Moranilt
Copy link
Author

Moranilt commented Sep 5, 2021

I said try it. It doesn't mean that should be your final solution but it may help figure out where the issue is.

The reason I suggest converting it is because your struct fields are capitalized and your selections are not, so how is the query expected to select the right field when the field names are not matching? Using the json.Marshal function your json tags will be respected and likely map properly.

I'm sorry. yeah, it will work, i knew it. But as @asif-mahmud said it doesn't work for nested structs and looks like this is a bug. I was expected to use nested structs.

@Moranilt
Copy link
Author

Moranilt commented Sep 5, 2021

Exactly sqlx.Select is buinding good nested structs. But when I'm using this struct in graphql-resolver to return user it's not returning nested properties from struct user(in my case).

@bhoriuchi
Copy link
Contributor

bhoriuchi commented Sep 7, 2021

I think the package just doesn't work that way. The executeSubFields (https://github.com/graphql-go/graphql/blob/master/executor.go#L297) function builds a map[string]interface{} from the resolvers. Since go is strongly typed I'm not sure how its expected to return your expected struct. GraphQL traverses the type and resolves each field individually and builds a resulting object from that. This is how the js reference implementation works. the only thing you can probably do here is add custom resolvers on to each of the fields in your nested struct that return the value of that field but your result from a query will still likely be a map[string]interface{}

@asif-mahmud
Copy link

asif-mahmud commented Sep 7, 2021 via email

@Moranilt
Copy link
Author

I think the package just doesn't work that way. The executeSubFields (https://github.com/graphql-go/graphql/blob/master/executor.go#L297) function builds a map[string]interface{} from the resolvers. Since go is strongly typed I'm not sure how its expected to return your expected struct. GraphQL traverses the type and resolves each field individually and builds a resulting object from that. This is how the js reference implementation works. the only thing you can probably do here is add custom resolvers on to each of the fields in your nested struct that return the value of that field but your result from a query will still likely be a map[string]interface{}

Yeah, probably is the best way to add my own resolver, but we are losing strict return value. It will be always map[string]interface{}. It's not gorgeous solution.

@noragem
Copy link

noragem commented Nov 5, 2021

I have the same issue. Is there any way to fix it?

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

4 participants