In short, this resolver getAllArticles()
returns an array of Articles, and each article has an Author Field and a Tags Field, so each article can fire the sub-resolver to get that data, but I was having trouble seeing and finding the best solution.
You have to know some backstory:
app.js
I am passing the DB connections into the top-level resolvers as a map in the root value.
const db = new Map()
db.set('Neo4J', Neo4J.getDriver())
db.set('MongoDB', MongoDB.getDB())
// GraphQL Endpoint
app.use('/graphql', bodyParser.json(), graphqlExpress((req) => {
// ...
return {
schema,
context,
rootValue: {
db
}
}
}))
getArticle.js
I am passing the db connections to the sub-resolvers by assigning them onto the response object.
const getArticle = async (root, args, context) => {
const db = root.db
const Neo4J = db.get('Neo4J')
const MongoDB = db.get('MongoDB')
// ...
const article = { /* ... */ }
return Object.assign({}, article , { db })
}
This worked excellent (code has become extremely clean) until I moved to the getAllArticles()
resolver that returns an array of articles. I could not see how to attach the db
Map.
getAllArticles.js
Here's what was immediately intuitive to add:
const getAllArticles = async (root, args, context) => {
const db = root.db
const Neo4J = db.get('Neo4J')
const MongoDB = db.get('MongoDB')
// ...
const articles = [{ /* ... */ }, { /* ... */ }, { /* ... */ }]
return Object.assign({}, articles, { db })
}
That didn't work, and after looking at it, why would it? Sub-resolvers take the data from the parent object, which is each Article in this case.
After some iterations, here is the viable solution:
app.js
everyResolver.js
Hopefully, this can help someone else in the future. I really like the approach of passing the DB driver connections into the resolvers. It tightened up the overall architecture and allows me to spin up additional resolvers easily because they come with batteries included.