Variables

In chapter 10, I showed you this query for the cart page:

POST /graphql HTTP/1.1
Host: api.shop.example
Content-Type: application/json

{
  "query": "{
    cart(id: 73) {
      totalCents
      items {
        productId
        quantity
        product {
          name
          description
          priceCents
        }
      }
    }
  }"
}

This is not quite the way a client would send the query. First, the query text is a JSON string, so it is enclosed in quotes and has no line breaks.

POST /graphql HTTP/1.1
Host: api.shop.example
Content-Type: application/json

{
  "query": "{ cart(id: 73) { totalCents items { productId quantity product { name description priceCents } } } }"
}

Next, the client replaces the hard-coded value 73 with a variable, $id, and declares the variable in the query.

POST /graphql HTTP/1.1
Host: api.shop.example
Content-Type: application/json

{
  "query": "query CartPage($id: ID!) { cart(id: $id) { totalCents items { productId quantity product { name description priceCents } } } }",
  "variables": { "id": "73" }
}

Notice how the query changed. It now begins with the word query and a name, CartPage. Before, the query began with a brace, which is allowed only for a query with no name and no variables. After the name, in parentheses, the query declares its variables: $id is a variable of type ID!. A variable’s name begins with $. Inside the query, cart(id: $id) uses the variable where the number used to be.

The variables field in the request body contains the values for the variables declared in the query. In this case, it maps the variable $id to the value "73". The server runs the query with the value "73" wherever the query uses $id. The response is the same as before.

Why the values are separate

A client that builds query text by pasting values into it takes some risks. A value that contains a quotation mark could break the query text. A value chosen by an attacker could change what the query means. Variables remove both problems. The query text does not change, and the server never reads a value as part of the query.

The API does not require variables. Using them is good practice for a client that builds queries from user-provided values. I include it here for your information only.