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, wishlists, 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:

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:

query myCartQuery{
  cart(cart_id: "1WxKm8WUm3uFKXLlHXezew5WREfVRPAn") {
    cart_id
    items {
      id
      qty
    }
    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:

{
  "data": {
    "cart": {
      "cart_id": "1WxKm8WUm3uFKXLlHXezew5WREfVRPAn",
      "items": [
        {
          "id": "5",
          "qty": 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.

query myCartQueryWithVariable($cart_id: String!) {
  cart(cart_id: $cart_id) {
    cart_id
    items {
      id
      qty
    }
    billing_address {
      firstname
      lastname
      postcode
    }
    shipping_addresses {
      firstname
      lastname
      postcode
    }
  }
}

Variables are defined separately in JSON:

{
  "cart_id": "1WxKm8WUm3uFKXLlHXezew5WREfVRPAn"
}

Product search queries

A product search query can contain the following components:

  • A full text search keyword
  • Filters (search criteria)
  • Pagination information
  • Sorting instructions

Specifying full text search keywords

The search element causes Magento to perform a full text search on the specified keywords. (This is the same type of search that is performed from the storefront. If multiple keywords are specified, each keyword is evaluated separately.)

The search element is optional, but it can be used with or without filters. Each query must contain a search or filter element.

Specifying filters

The filter element defines which search criteria to use to find the desired results. As with a REST call, each filter defines the field to be searched, the condition type, and the search value.

Search filters are logically ANDed unless an or statement is specified. The search query can contain unlimited number of nested or clauses. However, you cannot perform a logical or across two AND clauses, such as (A AND B) OR (X AND Y).

Search fields

Each object type defines which fields can be searched. See the object-specific documentation for details.

You cannot specify the same search field twice in a GraphQL query.

Condition types and search values

The following table lists available condition types and provides the SQL statement equivalents.

Magento GraphQL clause SQL equivalent
eq: "value" field = 'value'
neq: "value" field != 'value'
like: "value%" field LIKE 'value%'
nlike: "value%" field NOT LIKE 'value%'
in: [1, 2, 3] field IN (1, 2, 3)
nin: [1, 2, 3] field NOT IN (1, 2, 3)
notnull: true field IS NOT NULL
null: true field IS NULL
lt: "value" field < 'value'
gt: "value" field > 'value'
gteq: "value" field >= 'value'
lteq: "value" field <= 'value'
moreq: "value" field >= 'value'
from: "value1" to: "value2" field BETWEEN 'value1' AND 'value2'
finset: [1, 2, 3] FINSET(field, '1, 2, 3')

to and from must always be used together. These condition types can be used in the same search term. For example, qty: {from: "10" to: "20"}.

gt and lt can be used in the same search term. For example, qty: {gt: "10" lt: "20"}.

Specifying pagination

Magento’s GraphQL implementation of pagination uses offsets so that it operates in the same manner as REST and SOAP API requests.

The pageSize attribute specifies the maximum number of items to return. If no value is specified, 20 items are returned.

The currentPage attribute specifies which page of results to return. If no value is specified, the first page is returned. If you specify a value that is greater than the number of available pages, an error is returned.

You can include the total_pages attribute in the page_info section of the output definition to indicate how many pages were returned for the query.

Sorting instructions

The sort object allows you to specify which field or fields to use for sorting the results. If you specify more than one field, Magento sorts by the first field listed. Then, if any items have the same value, those items will be sorted by the secondary field. The value for each field can be set to either ASC or DESC.

In the following example, Magento returns a list of items that are sorted in order of decreasing price. If two or more items have the same price, the items are listed in alphabetic order by name.

sort: {
  price: DESC
  name:  ASC
}

Example Product Searches

The following sections provide examples of each type of search. These examples use the Magento Open Source sample data.

The following search returns items that contain the word yoga or pants. The Catalog Search index contains search terms taken from the product name, description, short_description and related attributes.

{
  products(
    search: "Yoga pants"
    pageSize: 10
  )
  {
    total_count
    items {
      name
      sku
      price {
        regularPrice {
          amount {
            value
            currency
          }
        }
      }
    }
    page_info {
      page_size
      current_page
    }
  }
}

The search returns 45 items.

Full text search with filters

The following sample query returns a list of products that meets the following criteria:

  • The product name, product description, or related field contains the string Messenger (which causes it to be available for full text searches).
  • The SKU begins with 24-MB
  • The price is less than $50.

The response for each item includes the name, sku, price and description only. Up to 25 results are returned at a time, in decreasing order of price.

{
  products(
    search: "Messenger"
    filter: {
      sku: {
        like: "24-MB%"
      }
      price: {
        lt: "50"
      }
    }
    pageSize: 25
    sort: {
      price: DESC
    }
  )
  {
    items {
      name
      sku
      description {
        html
      }
      price {
        regularPrice {
          amount {
            value
            currency
          }
        }
      }
    }
    total_count
    page_info {
      page_size
    }
  }
}

The query returns the following:

{
  "data": {
    "products": {
      "items": [
        {
          "name": "Wayfarer Messenger Bag",
          "sku": "24-MB05",
          "description": {
            "html": "<p>Perfect for class, work or the gym, the Wayfarer Messenger Bag is packed with pockets. The dual-buckle flap closure reveals an organizational panel, and the roomy main compartment has spaces for your laptop and a change of clothes. An adjustable shoulder strap and easy-grip handle promise easy carrying.</p>\n<ul>\n<li>Multiple internal zip pockets.</li>\n<li>Made of durable nylon.</li>\n</ul>"
          },
          "price": {
            "regularPrice": {
              "amount": {
                "value": 45,
                "currency": "USD"
              }
            }
          }
        },
        {
          "name": "Rival Field Messenger",
          "sku": "24-MB06",
          "description": {
            "html": "<p>The Rival Field Messenger packs all your campus, studio or trail essentials inside a unique design of soft, textured leather - with loads of character to spare. Two exterior pockets keep all your smaller items handy, and the roomy interior offers even more space.</p>\n<ul>\n<li>Leather construction.</li>\n<li>Adjustable fabric carry strap.</li>\n<li>Dimensions: 18\" x 10\" x 4\".</li>\n</ul>"
          },
          "price": {
            "regularPrice": {
              "amount": {
                "value": 45,
                "currency": "USD"
              }
            }
          }
        }
      ],
      "total_count": 2,
      "page_info": {
        "page_size": 25
      }
    }
  }
}

Simple search using a timestamp

The following search finds all products that were added after the specified time (midnight, November 1, 2017).

{
  products(
    filter: {
      created_at: {
        gt: "2017-11-01 00:00:00"
      }
    }
    pageSize: 25
    sort: {
      price: DESC
    }
  )
  {
    total_count
    items {
      name
      sku
      price {
        regularPrice {
          amount {
            value
            currency
          }
        }
      }
    }
    page_info {
      page_size
      current_page
    }
  }
}

The following example searches for all products whose sku begins with the string 24-MB or whose name ends with Bag.

{
  products(
    filter: {
      or: {
        sku: {
          like: "24-MB%"
        }
        name: {
          like: "%Bag"
        }
      }
    }
    pageSize: 25
    sort: {
      price: DESC
    }
  )
  {
    total_count
    items {
      name
      sku
      price {
        regularPrice {
          amount {
            value
            currency
          }
        }
      }
    }
    page_info {
      page_size
      current_page
    }
  }
}

The query returns 8 items.

This query searches for products that have name that ends with Short or has a sku that indicates the product is a pair of women’s shorts in size 10 (WSH%10%). The system performs a logical AND to restrict the results to those that cost from $40 to $49.99.

{
  products(
    filter: {
      price: {
        from: "40" to: "49.99"
      }
      name: {
        like: "%Short"
      }
      or: {
        sku: {
          like: "WSH%10%"
        }
      }
    }
    pageSize: 25
    sort: {
      price: DESC
    }
  )
  {
    total_count
    items {
      name
      sku
      price {
        regularPrice {
          amount {
            value
          }
        }
      }
    }
    page_info {
      page_size
      current_page
    }
  }
}

The query returns 1 item.