Reputation: 21277
I use express-graphql which is initialized with rootValue
and passes it to GraphQL's execute function. I wonder what is rootValue
's specification. I have seen some simple examples but I'm interested in full specification.
Upvotes: 3
Views: 1627
Reputation: 84777
The rootValue
is specific to the javascript implementation and, to my knowledge, not something that's explicitly required by the official specification.
This is the type definition for the resolve
function (or resolver) provided in the docs:
type GraphQLFieldResolveFn = (
source?: any,
args?: {[argName: string]: any},
context?: any,
info?: GraphQLResolveInfo
) => any
The first parameter passed to the resolver is the "source", "root" or "parent" value. A field is always associated with some Object type. The "source" value is simply the value that the field that returned that Object type resolved to. For example, given a query like:
{
user(id: 1) {
location {
city
}
}
}
The user
field returns an Object type. When it resolves, the resolved value is passed to the location
resolver as the "source". Similarly, when location
resolves, the resolved value is passed to the resolvers for all of its requested fields, like city
.
In our example, user
is field, like any other, it just happens to be on the Query
type, but that type itself is still an Object type. Because it's a field, it's resolved by calling the resolver associated with it. But because it's at the root of the query, there is no "source" value. This is the only purpose of the rootValue
you pass to execute
-- it gets passed to every root level resolver as the "source" value.
In other words, whatever you set rootValue
will be passed as the first parameter to the resolver for every field of the Query
, Mutation
and Subscription
types.
Since the rootValue
is only available to root level resolvers, it's very limited in its use. Any data that should be available to all resolvers should be included in the context instead.
For completion's sake, I should note that there are examples out there that show how to create a schema using SDL and buildSchema
. Because buildSchema
does not offer a way to provide resolvers for any fields, these examples provide a way to resolve the root level fields by passing in resolver functions through the rootValue
. This works because, as the docs note:
[If] a resolver function is not provided, then the default resolver is used, which looks for a method on source of the same name as the field. If found, the method is called with (args, context, info).
However, again, the rootValue
is only available to fields on the root types (Query, Mutation and Subscription). If you create a schema this way, you won't be able to define resolvers for fields on any other types. In other words, don't do it. See this answer for more details.
Upvotes: 6