I am modularizing my schema for a GraphQL API and trying to merge the resolvers without using any 3rd party libraries.
Is there a simple way to do this without Lodash.merge()
or equivalent?
The Apollo Documentation says to use a library such as Lodash to merge()
modularized resolvers. (http://dev.apollodata.com/tools/graphql-tools/generate-schema.html#modularizing)
The problem seems to be that by their nature, the resolvers contain functions as properties, so they seem to be omitted when I access them via Object.assign()
or even JSON.stringify()
.
If I console.log them, I see: {"Query":{},"Mutation":{}}
Here is what one of the resolvers looks like:
const productResolvers = {
Query: {
myProducts: (root, { userId }, context) => {
return [
{ id: 1, amount: 100, expiry: '12625383984343', created: '12625383984343' },
{ id: 2, amount: 200, expiry: '12561351347311', created: '12625383984343' },
{ id: 3, amount: 200, expiry: '11346347378333', created: '12625383984343' },
{ id: 4, amount: 350, expiry: '23456234523453', created: '12625383984343' },
];
},
},
Mutation: {
addProduct: (root, { userId }, context) => {
return { id: 350, amount: 100, expiry: '12625383984343', created: '12625383984343' };
},
}
};
Let's assume there is another one virtually identical called widgetResolvers
.
Here is a fully functional block of code:
export const schema = makeExecutableSchema({
typeDefs: [queries, mutations, productSchema, widgetSchema],
resolvers
});
Here is what I'm trying to achieve:
export const schema = makeExecutableSchema({
typeDefs: [queries, mutations, productSchema, widgetSchema],
resolvers: Object.assign({}, productResolvers, widgetResolvers)
});
I haven't loaded in ability to use rest spread yet (https://babeljs.io/docs/plugins/transform-object-rest-spread/). I suspect it won't work for the same reason Object.assign()
doesn't work.
Oh, and here is why I suspect this merge doesn't work: Why doesn't JSON.stringify display object properties that are functions?
If you're using Object.assign()
, your Query and Mutation properties shouldn't end up empty, but you will run into an issue because, unlike lodash's merge()
, it's not recursive. Object.assign()
only compares the "direct" properties of the objects it's passed -- overriding properties of previous sources as it moves through the list.
Because Query
and Mutation
are properties of the objects being passed, each subsequent resolver override the previous object's Query
and Mutation
, with the resulting object only holding the Query and Mutation properties of the last object passed into Object.assign()
.
It's a lot less neat, but if you're bent on avoiding importing lodash, you could get the expected behavior this way:
const productResolver = {
Query: { ... ✂ ... },
Mutation: { ... ✂ ... }
}
const widgetResolver = {
Query: { ... ✂ ... },
Mutation: { ... ✂ ... }
}
const resolvers = {
Query: Object.assign({}, widgetResolver.Query, productResolver.Query),
Mutation: Object.assign({}, widgetResolver.Mutation, productResolver.Mutation)
}
Got type resolvers too? No problem:
const Widget = { ... ✂ ... }
const Product = { ... ✂ ... }
const resolvers = Object.assign(
{
Query: Object.assign({}, widgetResolver.Query, productResolver.Query),
Mutation: Object.assign({}, widgetResolver.Mutation, productResolver.Mutation)
},
Widget,
Product)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With