I've read all the docs at graphql.org and the READMEs for graphql-js and express-graphql, and I cannot find a reference for the resolver function signature.
The GraphQL docs suggest:
(obj, args, context)
obj The previous object, which for a field on the root Query type is often not used.
args The arguments provided to the field in the GraphQL query.
context A value which is provided to every resolver and holds important contextual information like the currently logged in user, or access to a database.
But my brief testing with my new express-graphql server I just made (first one) suggests the signature GraphQL.js uses is:
(args, context, obj)
From my console debugging:
JSON.stringify(args) -> { "foo": "bar" }
Object.keys(context) ->
_consuming, baseUrl, method, session,
_dumped, client, next, sessionCookies,
_events, complete, originalUrl, sessionKey,
_eventsCount, connection, params, sessionOptions,
_maxListeners, domain, query, socket,
_parsedUrl, headers, rawHeaders, statusCode,
_passport, httpVersion, rawTrailers, statusMessage,
_readableState, httpVersionMajor, read, trailers,
httpVersionMinor, readable, upgrade,
res, url,
Object.keys(obj) -> fieldName, fieldNodes, fragments, operation, parentType, path, returnType, rootValue, schema, variableValues
(I just learned GraphQL/GraphQL.js last week, so I might be missing something obvious.)
wait.. what?
what is the current signature of the function under debug in this case?
and how the scheme looks like?
anyway, resolver signature should be:
obj, args, context, info
obj -> the object resolved, (rootQuery argument for root types (such as Query))
args -> { [key: string]: any } GraphQL Arguments, nothing much to eleborate
context -> shared object used for side effects
info -> Object containing information about the execution info, (context) in your case above
(Sorry, I had typos in the first post which I just fixed.)
What you described is not what I'm seeing. In my root resolvers, the first arg in the list is an object of input arguments for that field, and the second arg is clearly the context object.
@odigity just have a look at the source code and you find the signature. that is the way I find it in v0.5 update, that's when I met the error too.
If you look at the source, you can see the resolve function is passed source, args, context, info. You can see some example resolvers in starWarsSchema, which is linked to from the README.
The best non-source documentation for this is probably the "Execution" page on graphql.org, although it doesn't mention the info parameter and should perhaps be updated. Anybody care to submit a PR for that?
As I explained in careful detail in my initial post, the signature you're describing does not the match the results I'm getting. For example, I'm seeing args in the first position.
Do you have some sample code that we could look at? The snippets in your post aren't something that I could run and try to repro what you're seeing.
It'll take some time, but I'll try to get to it soon.
The GraphQLResolveInfo flow type is useful:
Closing this issue since it is starting to age.
The flow types and documentation should help, and you can also check out some of the examples and tests in this repository to see how resolvers are called with values.
What you might be running into is the default resolver, which attempts to look for a method on the source object with the name of the field requested, and if found calls that. In that case, source is not provided as a first argument since you can access that value with this.
For those who are still stumbling upon this issue, I've written an article that documents the internals of the info object and explains its role in the query resolution process. You can find it here.
@odigity I know what you were talking about. I was confused just like you were. I am using the buildSchema function from the graphql along with the express-graphql.
I didn't dive into the source code. The following is just my guess. Part of them are not listed clearly in the document but just a sentence:
When a resolver takes arguments, they are passed as one “args” object, as the first argument to the function.
-- Passing Arguments
I think the reason that all the first argument parentValue aka root were all omitted on purpose is that the value passed to the 1st level resolver is always null if not otherwise specified (see GraphQL Server Basics: The Schema), and all the resolvers (existing as methods of a class) from other levels get their parent values from the constructor. So still they just need the args as their first argument.
I have figured it out. If you do not explicity provide your own resolver, then then default resolver is used. This the behaviour when you use buildschema. What then happens is the default resolver will call your resolvers with (args, context, info). In order to access the root value, you would need to use the this object in you resolver as stated by @leebyron. Note that you need to use function() {} when defining the resolver otherwise an arrow function will have an empty this object.
@Alappin you are right. I listed I'm using express-graphql along with the graphq-js utility buildSchema and tried to dive into the source code. I only described the symptoms and to whom wants to know why, here's my situation:
When we use buildSchema(), we don't define resolvers in the definition. The schema will use default resolvers:
http://graphql.org/graphql-js/utilities/#buildschema
Instead we have to provide rootValue to the graphql() function as described here:
https://github.com/graphql/express-graphql#options
Since no _real_ resolvers are provided to the execute, the defaultFieldResolver will be used during resolving:
https://github.com/graphql/graphql-js/blob/dda7c4a9abf8306a1bbc646a4394a74e63dd369f/src/execution/execute.js#L585
When we think the resolveFn is called with the root or parent value as the first param:
https://github.com/graphql/graphql-js/blob/dda7c4a9abf8306a1bbc646a4394a74e63dd369f/src/execution/execute.js#L650
instead the function is actually a defaultFieldResolver. It's like a proxy which calls the contained function by the matched key of the rootValue or just return the value:
https://github.com/graphql/graphql-js/blob/dda7c4a9abf8306a1bbc646a4394a74e63dd369f/src/execution/execute.js#L1160
Most helpful comment
For those who are still stumbling upon this issue, I've written an article that documents the internals of the
infoobject and explains its role in the query resolution process. You can find it here.