How to Use GraphQL API in Magento 2 for Headless Commerce

Magento 2 provides a GraphQL API that enables headless commerce architectures. GraphQL allows frontend applications to request exactly the data they need in a single request, making it the preferred API for PWA storefronts and custom frontends. Understanding how GraphQL behaves differently from the traditional Magento frontend helps avoid unexpected issues.

GraphQL Endpoint

The GraphQL endpoint is available at:

https://your-store.com/graphql

For multi-store setups, include the store code in the header:

Store: store_view_code

Common Queries

Product Search

{
  products(search: "jacket", pageSize: 10, currentPage: 1) {
    total_count
    items {
      sku
      name
      price_range {
        minimum_price {
          regular_price {
            value
            currency
          }
        }
      }
      small_image {
        url
        label
      }
    }
  }
}

Category Listing

{
  categoryList(filters: { ids: { eq: "42" } }) {
    id
    name
    product_count
    children {
      id
      name
      url_path
    }
  }
}

Cart Operations

mutation {
  addProductsToCart(
    cartId: "cart-id-here"
    cartItems: [
      {
        quantity: 1
        sku: "product-sku"
      }
    ]
  ) {
    cart {
      items {
        id
        product {
          name
          sku
        }
        quantity
      }
    }
  }
}

Authentication

Guest Operations

Cart creation, product browsing, and category listing work without authentication. Create a guest cart:

mutation {
  createEmptyCart
}

Customer Operations

For customer-specific operations (viewing orders, managing account, accessing wish lists), include a customer token in the Authorization header:

mutation {
  generateCustomerToken(email: "[email protected]", password: "password") {
    token
  }
}

Then include the token in subsequent requests:

Authorization: Bearer <customer-token>

Tokens have a configurable expiration time set in Stores → Configuration → Services → OAuth → Access Token Expiration.

Sorting Behavior: GraphQL vs Frontend

Magento uses different backends for GraphQL and the traditional (Luma/Hyva) frontend:

  • Frontend catalog queries: MySQL-based queries
  • GraphQL product queries: Elasticsearch/OpenSearch-based queries

This means sorting results can differ between the two channels when multiple products have the same relevance score or position value. For example, products with identical position values in a category may appear in different orders via GraphQL compared to the frontend.

This is expected behavior, not a bug. The two engines use different tiebreaker logic for equal-score results.

Solution: If consistent ordering across both channels is important, use explicit secondary sort criteria in GraphQL queries:

{
  products(
    filter: { category_id: { eq: "42" } }
    sort: { position: ASC, entity_id: ASC }
    pageSize: 20
  ) {
    items {
      sku
      name
    }
  }
}

Adding entity_id (or another unique field) as a secondary sort ensures deterministic ordering regardless of the backend engine.

Schema Introspection

Explore the available queries and mutations using introspection:

{
  __schema {
    queryType {
      fields {
        name
        description
      }
    }
    mutationType {
      fields {
        name
        description
      }
    }
  }
}

Tools like GraphQL Playground, Altair, or Insomnia provide visual interfaces for exploring the schema and testing queries.

Performance Considerations

  • Request only needed fields: GraphQL's advantage is requesting only the data you need. Avoid requesting all available fields on product queries.
  • Use pagination: Always include pageSize and currentPage parameters. Requesting entire catalogs in a single query overwhelms the server.
  • Cache GraphQL responses: Magento supports HTTP caching for GET-based GraphQL queries. Configure Varnish or CDN caching for frequently requested queries.
Loading...