1. Home
  2. Docs
  3. Getting Started
  4. Queries

Queries

On this page, you’ll learn in detail about how to query a WPGraphQL server.

Fields

At its simplest, GraphQL is about asking for fields on objects. Let’s start by looking at a simple query and the result we get when we run it:

You can immediately see that the query has the same shape as the result. This is essential to GraphQL. As a consumer the results are predictable as you get back data in the shape you requested it, and the server is aware of what fields are being asked for before execution.

In this case, the field url returns a String, which is essentially equivalent to the WordPress  function get_bloginfo( 'url' );. 

Nested Fields

In the previous example, we just asked for the url from General Settings, which returned a string. But fields can also refer to objects. In that case, you can make sub-selections on fields of that object. GraphQL queries can traverse related objects and their fields, letting clients fetch lots of related data in a single request, instead of making many roundtrip requests as would be needed when interacting with a typical REST API.

In this example, we’re querying multiple different fields from different settings groups in a single request.

Arguments

If the only thing GraphQL could do was traverse objects and their fields, GraphQL would already be useful for data fetching. But when you add the ability to pass arguments to fields, things get much more interesting. 

In a system like REST, you can only pass one set of arguments, the query parameters and URL segments in your request. But in GraphQL, each field and nested object can get their own set of arguments making GraphQL a complete replacement for making multiple roundtrip API requests. You can even pass arguments to scalar fields to implement data transformations once on the server, instead of every client separately.

Arguments can be of many different types. In the above example, for the format argument, we have used an Enumeration type, which represents one of a finite set of options (in this case, format for the content field can be either RENDERED or RAW). 

Aliases

You may have noticed that since the result object fields match the name of the field in the query, but don’t include arguments, you can’t directly query for the same field with different arguments. That’s why we need aliases. Aliases in GraphQL let you rename the result of the field to anything you want:

In the above example, the two pageBy fields would have conflicted, but since we can alias them to different names, we can get both results in one request. 

Aliases can also be very powerful when building re-usable components, as you can alias the request to make sure the data comes back in the shape your component is expecting without making the transformation on the client. 

Fragments

Let’s say we had a relatively complicated page in our app that let us look at 2 pages side-by-side. You could imagine that query could quickly get complicated because we would need to repeat the fields at least once, one for each page being compared. 

That’s why GraphQL includes reusable units called fragments. Fragments let you construct sets of fields, and then include them in queries where you need to. Here’s an example of how you could solve the above situation with fragments: 

You can see how the above query would be pretty repetitive if the fields were repeated. The concept of fragments is frequently used to split complicated application data requirements into smaller chunks, especially when you need to combine lots of UI components with different fragments into one initial data fetch.

In component based UI development, fragments can be co-located with the components that render the data, easing the maintenance burden as the data dependencies are managed where the data is needed for rendering.

Operation Name

Up until now, we’ve been using a shorthand syntax where we omit the query keyword and the query name, but in production apps, it’s useful to use these things to make our code less ambiguous. 

Here’s an example that includes the keyword query as the operation type and GetSettings as the operation name.

GraphQL will respect the operation type query, mutation or subscription (NOTE: WPGraphQL currently doesn’t support subscriptions, but could some day) which describes the type of operation you’re intending. The operation type is required unless the shorthand syntax is used, and in that case, you can’t supply variable definitions or an operation name, and the operation type will default to query.

The operation name is a meaningful and explicit name for your operation. It is only required in multi-operation requests, but its use is encouraged because it is very helpful for debugging and server-side logging. 

Variables

So far, we have been writing all our arguments inside the query string. But in most applications, the arguments to fields will be dynamic: For example, there might be a dropdown that lets you select the Post Status to filter posts by, or a search field, or a set of filters. 

It wouldn’t be a good idea to pass these variables into the query string directly, because then our client-side code would need to dynamically manipulate the query string at runtime, and serialize it into GraphQL-specific format. Instead, GraphQL has a first-class way to factor dynamic values out of the query, and pass them as a separate dictionary. These are called variables. 

When we start working with variables, we need to do three things:

  1. Replace the static value in the query with $variableName
  2. Declare $variableName as one of the variables accepted by the query
  3. Pass variableName: value in the separate, JSON variables dictionary

Here’s an example of using variables:

Now, in our client code, we can simply pass a different variable rather than needing to construct an entirely new query. 

This is also in general a good practice for denoting which arguments in our query are expected to be dynamic – we should never be doing string interpolation to construct queries from user-supplied values.

Variable definitions 

The variable definitions are the part that looks like ($uri: String) in the query above. It works just like the argument definitions for a function in a typed language. It lists all of the variables, prefixed by $, followed by their type, in this case String.

All declared variables must be either scalars, enums, or input object types. So if you want to pass a complex object into a field, you need to know what input type that matches on the server. 

Variable definitions can be optional or required. In the case above, since there isn’t an ! next to the Episode type, it’s optional. But if the field you are passing the variable into requires a non-null argument, then the variable has to be required as well.

To learn more about the syntax for these variable definitions, it’s useful to learn more about the GraphQL schema language. 

Default variables 

Default values can also be assigned to the variables in the query by adding the default value after the type declaration.

When default values are provided for all variables, you can call the query without passing any variables. If any variables are passed as part of the variables dictionary, they will override the defaults.

Directives

We discussed above how variables enable us to avoid doing manual string interpolation to construct dynamic queries. Passing variables in arguments solves a pretty big class of these problems, but we might also need a way to dynamically change the structure and shape of our queries using variables. For example, we can imagine a UI component that has a summarized and detailed view, where one includes more fields than the other.

Let’s construct a query for such a component:

Try editing the variables above to instead pass true for withDate, and see how the result changes.

We needed to use a feature in GraphQL called a directive. A directive can be attached to a field or fragment inclusion, and can affect the execution of a query in any way the server desires. The core GraphQL specification includes exactly two directives, which WPGraphQL respects:

  • @include(if: Boolean) Only include this field in the result if the argument is true.
  • @skip(if: Boolean) Skip this field if the argument is true.

Directives can be useful to get out of situations where you otherwise would need to do string manipulation to add and remove fields in your query. Server implementations may also add experimental features by defining completely new directives.

NOTE: WPGraphQL currently doesn’t have any custom directives defined, but if you have ideas, let us know!

Was this article helpful to you? Yes 1 No

How can we help?