If I'm not mistaken, the first argument to the resolve function of an extendConnection field should be the same root as that of the nodes function (the parent). It currently appears to be passed the connection resulting from the nodes function.
Ah, yeah I suppose it should that that same convenience shortcut. Feel free to open a PR to enable that, or I'll try and get to this (and #394) this weekend.
@tgriesser There are more issues.
The function for the global extension is never called and the response gets a non-null error. The plugin tests only check that the schema is update, but not whether the function is called.
To recap:
One-off extension: source/root and args are wrong
Global: function never called
I guess the real problem here is that the connection extensions are sub-fields, meaning that they are only passed the parent (connection) and their own args ({}).
I worked around this temporarily by using the makeResolveFn from within the resolve function and merging the result with the total.
The workaround using makeResolveFn directly has me wondering whether the plugin would be better if it didn't combine resolution with schema definition. In that respect, I think graphql-js-relay has it right, exposing functions for different kinds of resolvers. If .connectionField just made sure that the schema and types were in place, one could either import their, for example, REST-compatible resolve function or roll their own. It would also make connection extensions less brittle. At the end of the day, I wonder whether the resolution logic would be better off in separate modules.
Hi @jamiehodge,
I'm not sure if this has already been fixed or if I'm not getting the point of the issue here, but it looks like fields of extendConnection are receiving the same root & args params than nodes as shown on the screenshot below 馃憞. Am I missing something here? 馃

After some investigation, there are two things I noticed here:
export const User = objectType({
name: 'User',
definition(t) {
t.id('id');
t.string('name');
t.connectionField('PostConnection', {
type: 'String',
resolve: (root, args) => {
console.log({ root, args });
return {
edges: [
{
cursor: 'cursor1',
node: 'node1',
},
{
cursor: 'cursor2',
node: 'node2',
},
],
};
},
extendConnection(t) {
t.int('totalCount', {
resolve: (rootFromTotalCount, argsFromTotalCount, ctx) => {
console.log({ rootFromTotalCount, argsFromTotalCount });
return 5;
},
});
},
});
},
});
rootFromTotalCount has type any where I guess it should have the same type as the root from the resolve function above (the one to resolve the connectionField){
user {
id
name
PostConnection(first: 5) {
edges{
cursor
node
}
totalCount
}
}
}
Here's what gets printed to the console:

I think that rootFromTotalCount and argsFromTotalCount should be the same as root and args right ? As @jamiehodge pointed out, it appears that the root in an extendConnection field get passed the result from the connection's resolve function.
When extending the connection globally like in your example, the rootFromTotalCount appears to have the correct type but it looks like the totalCount function is never executed (although I query for the totalCount field)
Thanks a lot for the explanations @tatchi, that's super useful! 馃檹
I think that rootFromTotalCount and argsFromTotalCount should be the same as root and args right ?
So, after further investigation, this is AFAIK the expected result. In your example, totalCount is a field of the <X>Connection type. eg:
type PostConnection {
"""
https://facebook.github.io/relay/graphql/connections.htm#sec-Edge-Types
"""
edges: [PostEdge]
"""
https://facebook.github.io/relay/graphql/connections.htm#sec-undefined.PageInfo
"""
pageInfo: PageInfo!
totalCount: Int # <-- totalCount field
}
Meaning that the root param _should_ be the parent (this is all handled by graphql-js anyway) and the parent here _is_ the result from the resolve function. Same goes for the args param, the totalCount field has its own args as it's on a separate type.
Indeed, I've been confused sorry 馃槄 I might have also misunderstood what @jamiehodge explained.
Do you still confirm the two other issues (any root type while extending the connection per field and the resolver not being called when extending globally) ?
Most helpful comment
After some investigation, there are two things I noticed here:
1. Extending the connection per field
rootFromTotalCounthas typeanywhere I guess it should have the same type as therootfrom theresolvefunction above (the one to resolve theconnectionField)Here's what gets printed to the console:
I think that
rootFromTotalCountandargsFromTotalCountshould be the same asrootandargsright ? As @jamiehodge pointed out, it appears that therootin anextendConnectionfield get passed the result from the connection'sresolvefunction.2. Extending the connection globally
When extending the connection globally like in your example, the
rootFromTotalCountappears to have the correct type but it looks like thetotalCountfunction is never executed (although I query for thetotalCountfield)