Querying Relationships
So now that we have all of our relationships set up, let's really push GraphQL with the following query
{
viewer {
name
email
jobs(first: 2) {
edges {
node {
id
title
user {
name
email
}
tasks(first:10) {
edges {
node {
title
users(first: 5) {
edges {
node {
name
email
}
}
}
}
}
}
}
}
}
}
}
Wow... that's a large query so let's break down what we're asking for.
Viewer
Here, we're asking for the authenticated user's name and email.
Viewer > Jobs
This is asking for the first 2 jobs that belong to the authenticated user along with it's id and title.
Viewer > Jobs > User
For each job we're also asking for the user who created it.
Viewer > Jobs > Tasks
For each job, we're asking for the first 10 tasks assigned to it.
Viewer > Jobs > Tasks > Users
For each task, provide us with the name and email of the first 5 users assigned to it.
Now let's run it and see what happens.
Alright, if you didn't see what the benefits were with GraphQL before hopefully this will help make it clear. We're able to traverse the relationships of our types without creating a new endpoint for each one.
Now if you're really ahead of the game, you may be saying... okay, that's pretty slick, but how many calls is this making to the database. Well, right now you're DB is begging you for mercy as each one of these fields is querying the DB.
To test this out, let's update our ViewerQuery to log each time the DB is queried.
// app/Http/GraphQL/Queries/ViewerQuery.php
class ViewerQuery extends GraphQLQuery
{
// ...
/**
* Resolve the query.
*
* @param mixed $root
* @param array $args
* @return mixed
*/
public function resolve($root, array $args)
{
$queries = 0;
\DB::listen(function ($query) use (&$queries) {
++$queries;
\Log::info("DB was queried {$queries} times.");
});
return auth()->user();
}
}
And let's rerun the query and check our log
[2016-12-22 22:47:52] local.INFO: DB was queried 1 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 2 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 3 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 4 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 5 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 6 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 7 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 8 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 9 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 10 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 11 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 12 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 13 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 14 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 15 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 16 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 17 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 18 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 19 times.
[2016-12-22 22:47:52] local.INFO: DB was queried 20 times.
YIKES! Our DB admin would come hunt us down if we released something like this to production! But don't worry, Lighthouse and graphql-php provides you with some help to really optimize your queries and reduce the calls to your DB.