Resolver
Root fields (rootValue
) declare all the possible entries for our GraphQL API. These Entries are called Resolver
.
The syntax of a resolver is as following:
resolverFn(obj, args, context, info) {
return context.db.loadHumanByID(args.id).then(
userData => new Human(userData)
)
}
obj
: therootValue
objectargs
: the arguments passed in this function from querycontext
: the current context, used to connect to database or define logged in user, ...info
: the meta data for the current query and schema details
Note: by default, if you put this resolverFn
in the rootValue
, the obj
field will be ommited and populated by default and the resolverFn
will be called as (args, context, info)
.
If you want to use the obj
field, you can always refer by this
. For example:
var rootValue = {
findAllUserByUsername: (args, context, info) => {
console.log("find filter username", obj, args, context, info);
return database.filter((user) => user.username == username);
},
}
var resolverFn = (obj, args, context, info) => {
console.log("resolve fn", obj, args, context, info)
}
if you see in here, the reoslveFn
will take 4 parameters including the obj
whereas the findAllUserByUsername
only takes 3 parameter without the obj
For this fieldResolver
function to be effective, we can use within our main entry point graphql()
function as following:
graphql({ schema, source, rootValue, fieldResolver: resolverFn }).then((response) => {
console.log(JSON.stringify(response, null, 2));
});
if the resolver name is not in rootValue
, GraphQL will fall back to fieldResolver
function
Same thing with TypeResolver
. However by providing this resolver, we lost the magic behind GraphQL.
GraphQL default resolver
By default we can just query graphql by simply putting in the field type.
For example, if we have:
var database = [
{
username: "Test1",
password: "test"
},
{
username: "Test2",
password: "test"
},
{
username: "Test3",
password: "test"
}
]
With resolvers:
var rootValue = {
users: () => {
return database;
},
}
And we query graphql as
{
users: {
username
}
}
as the users
return the database
, the username
is automatically resolved by GraphQL and returns
{
"data": {
"users": [
{
"username": "Test"
},
{
"username": "Test2"
}
]
}
}
This is because of GraphQL default resolvers, it assumes that if the resolver for a field isn't provided, the property of the same name should be read and returned
However, if we overwrite with our resolverFn
in fieldResolver
, this does not work anymore:
graphql({ schema, source, rootValue, fieldResolver: resolverFn }).then((response) => {
console.log(JSON.stringify(response, null, 2));
});
which will returns
{
"data": {
"users": null
}
}