graphql-weaver
graphql-weaver copied to clipboard
Access to rootValue
Hi! I've tried weaving two schemas, one of which was queried before using graphql-js' rootValue argument. The resulting schema however does not seem to be getting the rootValue that is set.
Steps to reproduce: Run one of the following examples:
- Apollo Launchpad example
- Code on Node.js:
const {
graphql,
GraphQLObjectType,
GraphQLSchema,
GraphQLString,
} = require('graphql');
const { weaveSchemas } = require('graphql-weaver');
const beverageSchema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'beverage',
fields: {
beverage: {
resolve: (root, args, ctx, ast) => {
if (
(root && root.bar) ||
(ast && ast.rootValue && ast.rootValue.bar)
) {
return '🍺';
}
return '💧';
},
type: GraphQLString
}
},
})
});
const foodSchema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'food',
fields: {
food: {
resolve: () => '🍔',
type: GraphQLString
}
},
})
});
// http://graphql.org/graphql-js/graphql/#graphql
graphql(
beverageSchema,
'{ beverage }'
).then(result => {
console.assert(
result.data.beverage == '💧',
'beverage schema without root did not return 💧'
);
}).catch(e => {
console.log(e);
});
graphql(
beverageSchema,
'{ beverage }',
{ bar: true }
).then(result => {
console.assert(
result.data.beverage == '🍺',
'beverage schema with root did not return 🍺'
);
}).catch(e => {
console.log(e);
});
graphql(
foodSchema,
'{ food }'
).then(result => {
console.assert(
result.data.food == '🍔',
'food schema did not return the 🍔'
);
}).catch(e => {
console.log(e);
});
weaveSchemas({endpoints: [
{ schema: beverageSchema },
{ schema: foodSchema },
]}).then(theGrandSchema => {
graphql(
theGrandSchema,
'{ beverage }'
).then(result => {
console.assert(
result.data.beverage == '💧',
'the grand schema without root did not return 💧'
);
});
graphql(
theGrandSchema,
'{ beverage }',
{ bar: true }
).then(result => {
console.assert(
result.data.beverage == '🍺',
'the grand schema with root did not return 🍺'
);
}).catch(e => {
console.log(e);
});
graphql(
theGrandSchema,
'{ food }'
).then(result => {
console.assert(
result.data.food == '🍔',
'the grand schema did not return the 🍔'
);
}).catch(e => {
console.log(e);
});
});
Expected behaviour:
Queries on the beverage
root with a { bar: true }
set as root should return "🍺 "
.
Actual behaviour
Queries on the beverage
root with a { bar: true }
set return "💧 "
.
Thanks for your feedback. You're correct, the rootValue
is currently not propagated. It makes sense to propagate the rootValue
to endpoints without namespace declaration, like in your example. Does your use case also include endpoints with namespaces? I think it would still be a good idea to set the rootValue
in the GraphQLResolveContext
, but what about source
? Should it be set to the rootValue`? Should we just try to access a field on the rootValue with the same name as the namespace on the endpoint?
hmm... in my particular case only the "old" schema, which has no namespace declaration, would use a rootValue,
the other weaved schemas with namespaces are from upstream services, so the rootValue
is not really useful to them. But I can imagine that other people might try to weave local schemas that implement patterns such as the one DataLoader per request with namespaces. Using fields with the same name on the rootValue
sounds good.