What is GraphQL?
GraphQL is an open-source data query and manipulation language for APIs and a query runtime engine
What is MongoDB?
MongoDB is a source-available cross-platform document-oriented database program.
That's cool, but why are they "perfect for each other?"
In this article I'll assume you have an existing understanding of the way GraphQL and MongoDB work, after all this isn't a tutorial but rather an explanation of why MongoDB and GraphQL are perfect for one another.
Now onto the good stuff.
If you want to view a list of posts you might send a query like:
{
posts {
title
content
}
}
As you can see we're asking our GraphQL API for a list of posts, which will give us back the title and content fields on each respective post. The function to return this data might look something like:
const resolvers = {
Query: {
posts() {
return PostModel.find({})
},
},
};
On its own, this isn't very notable, but cool stuff starts to happen when you leverage the Document nature of MongoDB.
Nearly every Object in HiddenLayer's database contains a subdocument called Insights
which represents various forms of data. For example, the counts of a number of replies on a post. Typically if you were using an SQL style of database this would live in another table.
So what if it lives in another table?
The simple answer is less time spent on doing stuff on the database.
The query to get a post and its insights
would be:
{
posts {
title
content
insights {
totalReplies
}
}
}
And its corresponding resolver code querying a MongoDB collection.
const resolvers = {
Query: {
// The same resolver from before
posts() {
return PostModel.find({})
},
},
Insight: {
// A field resolver that will let us return a sub-object within each `Post` object
insights(parent) {
// This functions first argument will always be the object returned from the parent resolver.
// We can just grab the object and return its insights object which already exists on the document
return parent.insights;
}
}
};
Because the insights
field already exists and is stored directly on the post we add no additional database overhead to fetch this data. If we were to write this resolver using an SQL database it might look something like:
const resolvers = {
Query: {
posts() {
return db.query('SELECT post, title FROM posts');
},
},
Insight: {
// A field resolver that will let us return a sub-object within each `Post` object
insights(parent) {
// We now have to add another database query to fetch and return this data.
return db.query('SELECT totalReplies FROM insights WHERE post_id = $(id)', { id: parent.id, });
},
},
};
What ends up happening is that we run the query for the insights
table for every single post. So if we fetch 50 posts, that means 50 additional queries to fetch the insights
. Initially this may not seem like much, but if there's a lot of data and depth in these relation/sub object fields you end up with enormous amounts of database queries.
I think this is where MongoDB & GraphQL truly shine. MongoDB's data storage structure already represents data the same way as GraphQL, we can leverage the deeply nested data to return a lot of information back to the consumer with very minimal overhead.
I plan on turning these articles into a series, in the upcoming articles I'll deep dive into how this impacts HiddenLayer's queries in production using more in depth code examples. If this interests you be on the lookout.
If you'd like to learn more about HiddenLayer, I'd encourage you to head over to https://hiddenlayer.app
Original article: https://programming.hiddenlayer.app/c/mongodb/post/why-mongodb-and-graphql-are-perfect-for-each-other-ee7f