Queries

A GraphQL query retrieves data from the Magento server in a similar manner as a REST GET call. The current set of Magento GraphQL queries allow a mobile app or browser to render a wide variety of information, including the following:

  • A set of products to be displayed. This can include the entire catalog or those that match customer-specified criteria.
  • Customer data. With a customer token, a query can retrieve basic information about a customer as well as billing and shipping addresses, wish lists, order history, and other sensitive data.
  • Shopping cart contents. GraphQL supports both guest and logged-in customer carts.
  • Store configuration values, including theme and CMS settings, the currency code, and supported countries.

The Magento REST GET endpoints retrieve a wide variety of information on behalf of the merchant. Many of these endpoints are for retrieving backend information. For example, the GET /V1/customers/search endpoint can be used to find a subset of customers that meet certain criteria, such as those that live in a particular state or have a birthday this month. Likewise, the GET /V1/invoices endpoint can return all the recently-generated invoices. This type of functionality is not required for the frontend, so it is not available in GraphQL queries. The queries are designed to improve the customer’s user experience by quickly retrieving the data needed to render pages.

Over time, the Magento GraphQL queries will duplicate the functionality of all storefront-facing GET calls, while making it possible to query more data in one request. The main difference will be that GraphQL will support storefront use cases, while REST will support admin use cases.

Structure of a query

A query contains the following elements:

  • The optional keyword query. If no keyword is specified at the beginning of a request, the processor assumes the request is a query.
  • An operation name for your local implementation. This name is required if you include variables. Otherwise, it is optional.
  • The query name
  • The terms to search for. The terms can be in the form of objects, attributes, or a combination. Queries that don’t require search terms obtain their context from the customer’s authorization token or store ID, both of which are specified in the header of the call.
  • The output object, which specifies which data the query returns.

The following example shows the structure of the cart query:

1
2
3
query myCartQuery{
  cart(cart_id: String!): Cart
}

In the preceding example, myCartQuery identifies your implementation of the cart query. cart_id is a non-nullable string that defines the cart to query. (The exclamation point indicates the value is non-nullable.) The Cart output object defines which fields to return.

Now let’s fully define a query:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
query myCartQuery{
  cart(cart_id: "1WxKm8WUm3uFKXLlHXezew5WREfVRPAn") {
    items {
      id
      quantity
    }
    billing_address {
      firstname
      lastname
      postcode
      }
    shipping_addresses {
      firstname
      lastname
      postcode
    }
  }
}

In this example, we’ve supplied a cart ID as input, (which was generated by the createEmptyCart mutation). The output includes the cart_id as well as selected information about the items in the cart and the billing and shipping addresses.

The following example shows the query response:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
  "data": {
    "cart": {
      "items": [
        {
          "id": "5",
          "quantity": 1
        }
      ],
      "billing_address": {
        "firstname": "Veronica",
        "lastname": "Costello",
        "postcode": "49628-7978"
      },
      "shipping_addresses": [
        {
          "firstname": "Veronica",
          "lastname": "Costello",
          "postcode": "49628-7978"
        }
      ]
    }
  }
}

Magento will not run a query that is too complex. The number of fields, objects, and nodes are factors in determining the complexity of a query.

Query variables

Specifying variables in a query can help increase code re-use. Consider the following requirements when generating a query that contains one or more variables:

  • All variables must be declared up-front, immediately after the operation name.
  • Variables are typed: they can be scalar or an object.
  • You must use all declared variables. Object variables are defined in JSON.

The following example declares the $cart_id variable. It is referenced in the input statement.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
query myCartQueryWithVariable($cart_id: String!) {
  cart(cart_id: $cart_id) {
    items {
      id
      quantity
    }
    billing_address {
      firstname
      lastname
      postcode
    }
    shipping_addresses {
      firstname
      lastname
      postcode
    }
  }
}

Variables are defined separately in JSON:

1
2
3
{
  "cart_id": "1WxKm8WUm3uFKXLlHXezew5WREfVRPAn"
}

Introspection queries

Introspection queries allow you to return information about the schema. For example, you might want a list of Magento GraphQL queries or details about a specific data type. The GraphQL specification determines the structure of introspection queries. See Introspection for more information.

For Magento, introspection queries MUST have the operation name IntrospectionQuery. If you omit the operation name, or use a different name, the query returns incomplete results.

Example introspection queries

Return a list of Magento queries

The following query returns a list of Magento queries. The results are truncated.

Request

1
2
3
4
5
6
7
8
9
10
query IntrospectionQuery {
  __schema {
    mutationType {
      fields {
        name
        description
      }
    }
  }
}

Response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "data": {
    "__schema": {
      "queryType": {
        "fields": [
          {
            "name": "cart",
            "description": "Returns information about shopping cart"
          },
          {
            "name": "category",
            "description": "The category query searches for categories that match the criteria specified in the search and filter attributes."
          }
        ]
      }
    }
  }
}

Get details about a data type

The following introspection query returns details about the ProductAttributeFilterInput data type.

Request

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
query IntrospectionQuery {
  __type(name: "ProductAttributeFilterInput") {
    name
    kind
    description
    inputFields {
      name
      description
      defaultValue
    }
    fields {
      name
      args {
        name
        description
        type {
          kind
          name
        }
      }
      type {
        kind
        name
      }
    }
  }
}

Response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{
  "data": {
    "__type": {
      "name": "ProductAttributeFilterInput",
      "kind": "INPUT_OBJECT",
      "description": "ProductAttributeFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.",
      "inputFields": [
        {
          "name": "category_id",
          "description": "Filter product by category id",
          "defaultValue": null
        },
        {
          "name": "description",
          "description": "Attribute label: Description",
          "defaultValue": null
        },
        {
          "name": "name",
          "description": "Attribute label: Product Name",
          "defaultValue": null
        },
        {
          "name": "price",
          "description": "Attribute label: Price",
          "defaultValue": null
        },
        {
          "name": "short_description",
          "description": "Attribute label: Short Description",
          "defaultValue": null
        },
        {
          "name": "sku",
          "description": "Attribute label: SKU",
          "defaultValue": null
        },
        {
          "name": "url_key",
          "description": "The part of the URL that identifies the product",
          "defaultValue": null
        }
      ],
      "fields": null
    }
  }
}