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.

results matching ""

    No results matching ""