Queries

The schema has a special type named Query, and its fields define the entry points of the API.

type Query {
  products: [Product!]!
  product(id: ID!): Product
  cart(id: ID!): Cart
  order(id: ID!): Order
}

With these four fields, a client can fetch

  • the list of products
  • a product given its identifier
  • a cart given its identifier
  • an order given its identifier.

A query begins with one of those fields. For example, earlier we saw a query for the cart page that begins with cart(id: 73). The (id: ID!) is the syntax for an argument.

Notice the types of the four fields. products is [Product!]!, a list of Product. The list is always there, even if it is empty. But the other three fields do not have a ! after their return types. It means that the return value can be null. These fields are nullable, because a lookup by identifier can fail. The identifier may not exist, or the user may not have permission to see it.

An order page

Suppose the phone app shows a confirmation page for order 91: when it was placed, the total, and for each item the product name, unit price, and quantity. Here is the query:

{
  order(id: 91) {
    placedAt
    totalCents
    items {
      productName
      unitPriceCents
      quantity
    }
  }
}

It begins with order, a field of Query. Every field named below it is a field of Order or OrderItem. It is sent as POST /graphql with the query in the JSON body, like the cart page.

Here is the response:

{
  "data": {
    "order": {
      "placedAt": "2026-09-21T14:03:00Z",
      "totalCents": 7300,
      "items": [
        {
          "productName": "Blue mug",
          "unitPriceCents": 1800,
          "quantity": 2
        },
        {
          "productName": "White mug",
          "unitPriceCents": 1500,
          "quantity": 1
        },
        {
          "productName": "Speckled mug",
          "unitPriceCents": 2200,
          "quantity": 1
        }
      ]
    }
  }
}

OrderItem has no product field. It has productName and unitPriceCents, copied from the product when the order is placed.

The schema as a contract

The schema is the agreement between the API and its clients. A client knows before it sends anything which fields exist, what type each one has, and which ones can be null. The server checks every query against the schema, and rejects one that names a field that does not exist before it looks at any data. A client can also ask the server for its schema, a feature called introspection, and a library or an editor can use the response to check a query while it is being written.