Have a strange problem...
Query to nested types return null.
But, if I return anything in parent type - resolve return right result
My code:
import { GraphQLList, GraphQLString, GraphQLID, GraphQLObjectType, GraphQLSchema } from 'graphql';
import AdminModel from '../models/Admin.model';
const AdminType = new GraphQLObjectType({
name: 'AdminType',
fields: {
_id: { type: GraphQLID },
login: { type: GraphQLString },
password: { type: GraphQLString }
}
});
const AdminRooteType = new GraphQLObjectType({
name: 'AdminRooteType',
fields: {
getAdmins: {
type: new GraphQLList(AdminType),
resolve() {
return AdminModel.find({})
}
}
}
})
export default new GraphQLSchema({
query: new GraphQLObjectType({
name: 'RootQuery',
fields: {
admin: {
type: AdminRooteType,
resolve() {
// EMPTY RESOLVE - EMPTY RESULT
}
}
}
})
});
Query:
{
admin {
getAdmins {
login
}
}
}
Result:
{
"data": {
"admin": null
}
}
If I changed returned value in fields admin in RootQuery:
import { GraphQLList, GraphQLString, GraphQLID, GraphQLObjectType, GraphQLSchema } from 'graphql';
import AdminModel from '../models/Admin.model';
const AdminType = new GraphQLObjectType({
name: 'AdminType',
fields: {
_id: { type: GraphQLID },
login: { type: GraphQLString },
password: { type: GraphQLString }
}
});
const AdminRooteType = new GraphQLObjectType({
name: 'AdminRooteType',
fields: {
getAdmins: {
type: new GraphQLList(AdminType),
resolve() {
return AdminModel.find({})
}
}
}
})
export default new GraphQLSchema({
query: new GraphQLObjectType({
name: 'RootQuery',
fields: {
admin: {
type: AdminRooteType,
#resolve() {#
#// RETURN ANYTHING HERE:#
# return 'foobar'#
}
}
}
})
});
I've got expected result:
{
"data": {
"admin": {
"getAdmins": [
{
"login": "123"
},
{
"login": "12asdf3"
}
]
}
}
}
What is right solution for this issue? (without using dummy values in return)
Thank's a lot!
What you are seeing is the expected behavior. Imagine we have a User
type with some fields:
const UserType = new GraphQLObjectType({
name: 'User',
fields: {
id: { type: GraphQLID },
name: { type: GraphQLString },
}
})
And a way to fetch a single user:
const QueryType = new GraphQLObjectType({
name: 'Query',
fields: {
user: {
type: AdminRooteType,
resolve: () => getUser(),
},
},
})
If getUser
returns an object representing a User
, the resolvers for all the fields (ie id
and name
on the User
type will be called.
When those fields (and whatever child fields they might have) resolve, you end up with a User object for the entire user
field to return. A response might look something like:
"data": {
"user": {
"id": 1,
"name": "Maria",
"comments": [
{
"id": 1,
// and so on...
}
]
}
}
Now, consider what happens when a user is not found and we return null instead. Our response looks like this:
"data": {
"user": null
}
It doesn't make sense to call any of the resolvers for the User fields. Would you expect the API to still return an id
or name
in this case? If it did, what values would those fields have? If we just returned a null id
and name
, how would the client distinguish that object from a User that existed but really did have id
and name
null values?
The point is, if a field returns a GraphQLObjectType and it resolves to null, none of the resolvers on the GraphQLObjectType will be called.
By unnecessarily nesting your getAdmins
field inside another GraphQLObjectType, you're forced to return some kind of object inside the resolver for admin
. So you will need to either live with that, or avoid creating an AdminRootType
altogether and just put the getAdmins
field on your Query type directly, as per convention:
const QueryType = new GraphQLObjectType({
name: 'Query',
fields: {
getAdmins: {
type: new GraphQLList(AdminType),
resolve: () => AdminModel.find({}),
},
},
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.