Reputation: 2597
I'm trying to simplify a graphql server using Apollo's graphql-tools. I want to do lazy-fetching, but not able to return a promise the way I could when using javascript classes as the resolvers.
Here's what I got:
Schema
type Customer {
details: Contact!
addresses: [Address]!
}
extend type Query {
customers(first: Int = 0, next: Int = 50): [Customer]
customer(id: Int!): Customer
}
Resolver
const domain1Resolvers = {
Query: {
customers: (_, {
first,
next
}) => customers(first, next)
}
};
resolving method:
const customers = (first, next) => {
return new Promise(resolve => {
var q =
`
SELECT *, company as organization FROM customer
ORDER BY id DESC
LIMIT ?, ?`;
sql.query(q, [first, next], function(err, rows) {
if (err) {
throw Error(err);
}
resolve(rows.map(r => {
return {
details: r,
addresses: () => getAddresses(r.id),
}
}));
});
})
};
The method getAddresses is invoked only if addresses is requested. In the class-based approach, I am able to have getAddresses return a Promise, but it will complain about not returning an Iterable if I try that using this mechanism. There must be some way of fetching addresses only when requested, but drawing a blank and so far not found an example.
Upvotes: 1
Views: 743
Reputation: 84657
To resolve a field on Customer only when it is requested, you would want to utilize the resolver for that particular field rather than the resolver for the customers
query. Your resolvers would look something like this:
const domain1Resolvers = {
Query: {
customers: (_, {
first,
next
}) => customers(first, next)
},
Customer: {
addresses: ({ details: { id } }) => getAddresses(id)
},
};
Upvotes: 2