-
Notifications
You must be signed in to change notification settings - Fork 842
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
Issue with embedded Struct response #170
Comments
How is your GraphQL Object defined? What are the resolve functions specified? |
@bbuck : My sample code is here - https://play.golang.org/p/wAJA_MPGPU
|
So that's kind of what I was thinking. You're not implementing a resolver for the "city" and "state" fields. I don't think it's really in the scope of the default resolver to search through nested struct fields, especially those that don't have a JSON struct tag specifying the name. Two solutions would be to either nest and "address" property, making the query: {
getUser {
address {
city
state
}
}
} The other is to implement the resolvers for those fields so they properly hunt the nested attribute correctly, you could make them generic functions by implementing an |
@bbuck : Can I keep city, state, name and email at same level instead of nesting? |
If you want to, that's fine. Your resolver just needs to know where to get that data from.
This is kind of fundamentally different. In this regard you're converting the entire struct into a JSON representation using struct tags to determine how to look at things. Here in GraphQL the default resolver is just piggybacking off the json struct tags to assume a field to resolve. However, if you define a field "city" on the At least that's how I see it. Resolving the object based on the config you can either match the the object definition to the struct or the struct to the object definition. But to deviate either layout from the other (like here with nested fields) you should be expected to provide a resolution function. Don't take my opinion as final, I just contribute here. Perhaps @chris-ramon or @sogko have their own ideas on how this should behave. |
I ran into this problem today, and I think that embedded structs should be handled in a more transparent way. I agree that this behavior should mimic |
You can work around this by implementing field-level resolve functions, but it is pretty inconvenient and not particularly intuitive/obvious. "city": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
m := p.Source.(User)
return m.City, nil
},
}, |
It'd be great to have an easy way of converting structs to simple (optionally nested) key : value pairs. It's probably a very popular use case to just dump a struct into an JSON API response. |
I agree that the default resolver should automatically look for fields on nested structs. |
I'm also facing this with interfaces. I'm using embedded structs that contain all fields of the interface. When implementing a concrete type I need to implement the Resolve function as states above. |
Met the same issue, the default resolver didn't search for nested struct although json.Marshal works. |
Any news on this? Is it planned to search nested structs like json.Marshal does for default resolvers? Or do I miss any way to somehow override the default resolver behaviour? |
Is this still the official position? I know how annoying nested structs are to deal with as library authors, but as consumers you just kind of expect nested structs to work everywhere. |
could we actually merge #371 ? |
Has this problem been solved? |
Running into this using
vs
|
Since the JSON returned from a composite structure gives the correct values for a schema, there should be no issue. Instead, the problem persists and limit us very much. |
same issue. I populated the Go struct type ResponseStatus struct {
Success bool `json:"success"`
}
type User struct {
Loginname string `json:"loginname"`
AvatarURL string `json:"avatar_url"`
}
type ValidateAccessTokenResponse struct {
ResponseStatus
User
ID string `json:"id"`
}
type UserDetail struct {
User
GithubUsername string `json:"githubUsername"`
CreateAt string `json:"create_at"`
Score int `json:"score"`
RecentTopics []RecentTopic `json:"recent_topics"`
} Got data: {
"data": {
"validateAccessToken": {
"avatar_url": null,
"id": "58e104cdc669764920c00964",
"loginname": null
}
}
} Solution: var UserBaseFields = graphql.Fields{
"loginname": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
switch t := p.Source.(type) {
// Both t.User.Loginname and t.Loginname are ok.
case *models.ValidateAccessTokenResponse:
return t.User.Loginname, nil
case *models.UserDetail:
return t.Loginname, nil
default:
return graphql.DefaultResolveFn(p)
}
}},
"avatar_url": &graphql.Field{
Type: graphql.String,
},
}
var UserType = graphql.NewObject(graphql.ObjectConfig{
Name: "User",
Description: "This respresents an user",
Fields: UserBaseFields,
})
var UserDetailType = graphql.NewObject(graphql.ObjectConfig{
Name: "UserDetail",
Description: "This respresents an user detail",
Fields: utils.MergeGraphqlFields(UserBaseFields, graphql.Fields{
"githubUsername": &graphql.Field{Type: graphql.String},
"create_at": &graphql.Field{Type: graphql.String},
"score": &graphql.Field{Type: graphql.Int},
"recent_topics": &graphql.Field{Type: graphql.NewList(RecentTopicType)},
}),
})
var AccessTokenValidationType = graphql.NewObject(graphql.ObjectConfig{
Name: "AccessTokenValidation",
Description: "The response type for validating accessToken",
Fields: utils.MergeGraphqlFields(UserBaseFields, graphql.Fields{
"id": &graphql.Field{Type: graphql.NewNonNull(graphql.ID)},
}),
}) Since |
not resolved yet? |
Noticed this issue when trying to resolve a field using a struct tag in an embedded field, like previous commenters have described in further detail. Thanks to the commenters here for providing some workarounds! |
This is still happening |
Yes, very annoying 🥲 |
type Address struct {
City string
json:"city"
State string
json:"state"
}
type User struct {
Name string
json:"name"
Email string
json:"email"
Address
}
My resolver is returning User struct, And I am getting following response :
{
"name":"Jon",
"email":"jon@email.com",
"city":null,
"state":null
}
Address is common struct shared by many sql tables.
How can I fix city and state response?
The text was updated successfully, but these errors were encountered: