How to Use GraphQL Operation Names and Variables

Operation names and variables are GraphQL features that help you write more readable, organized, and less ambiguous code.

Defining operation names

Until now, we have been using only the keywords query and mutation to name our API calls. However, it's a good idea to name our GraphQL operations with more specific and context-related names.

Using operation names on our API calls will make our code less ambiguous and help us identify which operation we're looking for while debugging.

Here's an example of an API call with an operation type of query and an operation name of GetFirstFiveOrders:

query GetFirstFiveOrders {
   orders(first: 5) {
       edges {
           node {
               id
               paymentStatus
               total
           }
       }
   }
}

The operation type identifies what type of operation we want to perform: query, mutation, or subscription. Learn more about GraphQL operation types.

The operation name is a meaningful and explicit name for an operation. Its use is optional unless you're working on a multi-operation document. However, we encourage you to name your operations because it is very helpful for debugging and server-side logging.

When an error occurs (you see errors either in your network logs or your GraphQL server logs), it is easier to find the operation in your codebase by name instead of trying to decipher the contents.

Think of the operation name as the function's name in your favorite programming language. In JavaScript, for example, we can create anonymous functions, but naming our functions makes our life easier when it comes to reading, refactoring, and debugging our code. Similarly, GraphQL operation and fragment names can help debug on the server side and identify different GraphQL requests.

Using variables

We've learned about arguments before. In the example we explored, we've been writing our argument inside the query string:

query {
 orderById(id: "a9acf424-931e-4fae-b1ee-a86bdc0e6076") {
   subTotal
   total
 }
}

However, in most cases, the arguments to fields will be dynamic. So, how can we pass dynamic arguments to our API calls?

In this case, we must use variables.

GraphQL has an elegant way of passing dynamic values to a query using a dictionary of variables.

In order to work with variables, we need to follow three steps:

  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, transport-specific (usually JSON) variables dictionary.

Here's what it looks like together:

query($orderId: String!) {
  orderById (id: $orderId) {
    total
  }
}

variables {
"orderId": "a9acf424-931e-4fae-b1ee-a86bdc0e6076"
}

If you're using the GraphQL Playground, make sure to enter variables in the variable pane, and do not include the word "variables" before the JSON object. See Using the variable pane.

By using variables, our client code can pass a different variable value rather than needing to construct an entirely new query for each API call. Using variables also helps us identify which arguments in our query are expected to be dynamic.

Defining variables

In the query above, $orderId: String! is the variable definition. Variable definitions work just like the argument definition for a function in a typed language. In GraphQL, a variable is prefixed by $, followed by its type (in this case, the scalar type String). Note the "!" beside the type (String!): that means the argument is required.

All declared variables must be either scalars, enums, or input object types.

Defining variables with complex objects

Passing complex objects as arguments into a field follows the same pattern:

mutation UpdateOrderStatus($myVar: UpdateOrderInput!) {
 updateOrder(input: $myVar) {
   order {
       comment
       shippingStatus
       paymentStatus
   }
   orderId
 }
}

variables {
 "myVar": {
  "comment": "Order paid. Package shipped.",
  "orderId": "66c4a31e-39a4-48b1-af00-5f14fd7a37d1",
  "shippingStatus": "SHIPPED",
  "paymentStatus": "PAID",
  "isHiddenFromUsers": false
 }
}

In the example above, named UpdateOrderStatus, we created a variable called $myVar that has a type of UpdateOrderInput. Then we declared $myVar as the variable we wish to pass to the input argument in the updateOrder mutation. Finally, we create the input object "myVar" in the variables dictionary.

Default variables

You can declare default values to variables by adding the default value after the type declaration:

query($orderId: String! = "a9acf424-931e-4fae-b1ee-a86bdc0e6076") {
  orderById (id: $orderId) {
    total
  }
}

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

What's next?

After learning GraphQL features that improve the readability of your code, it might be a good idea to know a feature that will help you to avoid unnecessary API calls and dramatically improve data fetching performance: GraphQL Aliases.