Get started with GraphQL

Learn how to manage your Project with GraphQL

GraphQL is an open-source query language that allows you to pull specified data from multiple sources with one call. For more information about GraphQL, visit graphql.org.

Learn more about how to use GraphQL with Composable Commerce in our self-paced GraphQL module.

Objectives of this guide

By the end of this guide you will have:

Placeholder values

Example code in this getting started guide uses placeholders that should be replaced with these values:

PlaceholderReplace withFrom
{projectKey}project_keyyour API Client
{region}your RegionHosts
${BEARER_TOKEN}your access tokenMake your first API call

Query your Project with GraphQL

A Composable Commerce GraphiQL IDE is available for evaluating and trying out commands.

GraphQL API requests can be executed using a POST call to the /graphql endpoint.

Use the GraphiQL IDE

  1. Go to https://impex.{region}.commercetools.com/graphiql
  2. Log in using your Merchant Center account.
  3. Ensure the correct Project is selected in the drop-down menu. Select the correct project in the GraphQL IDE
  4. Enter GraphQL queries in the left panel.

How to use autocomplete

When using the GraphiQL IDE, press ctrl+space to view a list of valid entries. Use the up/down arrow keys to navigate the list.

A screenshot displaying autocomplete in the GraphQL IDE

Use an API request

This example code shows how to return basic Project information.

Example GraphQL API request that returns Project information
POST https://api.{region}.commercetools.com/{projectKey}/graphql/
Authorization: Bearer ${BEARER_TOKEN}
{"query": "query ReturnProjectInformation { project { key createdAt }}"}
Returned Project informationjson
{
"data": {
"project": {
"key": "{projectKey}",
"createdAt": "2022-01-23T18:02:58.542Z"
}
}
}

How to structure GraphQL requests

The structure of GraphQL calls vary based on whether you want to query existing data, create entities, or update existing entities.

Query existing entities

Querying existing entities within your Project uses query. A name can be included to describe the call.

# Query existing data
query ReturnCustomers{}

Add an endpoint

In this example, customers targets all of our Customers. To target a single Customer, use customer.

query ReturnCustomers{
# Access the Customers endpoint
customers{
}
}
query ReturnASingleCustomer {
# Access the Customer endpoint
customer() {
}
}

Add query parameters

When querying an endpoint such as customers (where all Customers are targeted) these query parameters can be added based on your requirements.

ParameterActionExample use
whereOnly returns entities that match the Query Predicate. Quotation marks within quotation marks must be escaped.where: "firstName=\"John\""
sortChanges the order of the returned entities.sort: "lastName asc"
limitThe maximum number of results to return. The default value is 20.limit: 5
offsetUsed for skipping results. The default value is 0.offset: 1

When querying an endpoint like customer (where a single Customer is targeted) you must enter a unique identifier for the entity (usually its id or key).

Query parameters must be enclosed in () next to the endpoint:

query ReturnCustomers {
# Access the Customers endpoint
# Return five Customers named "John", ordered by their surname (ascending), and not including the first result
customers(where: "firstName=\"John\"", sort: "lastName asc", limit: 5, offset: 1) {
}
}
query ReturnASingleCustomer {
# Access the Customer endpoint
# Return a Customer based on their id
customer(id: "{customerID}") {
}
}

Choose what to return

When querying an endpoint such as customers (where all Customers are targeted) you can return the following:

  • offset is the same value you selected in the parameters.
  • count is the number of entities returned based on the limit parameter.
  • total is the total number of entities in your Project.
  • exists returns a boolean value to indicate whether a queried entity exists. For example, when checking whether an email address has already been registered by a Customer.
  • results is the object where you include the values (such as id or version) you want to be returned.

When querying an endpoint like customer (where a single Customer is targeted), you only choose the values of the entity to return.

# Query existing data
query ReturnCustomers {
# Access the Customers endpoint
# Return five Customers named "John", ordered by their surname (ascending), and not including the first result
customers(
where: "firstName=\"John\""
sort: "lastName asc"
limit: 5
offset: 1
) {
# Display the offset, count, and total
offset
count
total
# The values to return: The Customer's ID, version, email, and name are returned.
results {
id
version
email
firstName
lastName
}
}
}
query ReturnASingleCustomer {
# Access the Customer endpoint
# Return a Customer based on their id
customer(id: "{customerID}") {
id
version
email
firstName
lastName
}
}

Create and update entities

When creating or updating entities within your Project, use mutation. A name can be included to describe the call.

# Create a new entity
mutation CreateDiscountCode{}
# Update an existing entity
mutation DeactivateDiscountCode{}

Add an action

Instead of requiring an endpoint, the mutation requires an action. The chosen action determines whether you are creating a new entity or updating an existing one.

If using the GraphiQL IDE, use autocomplete to view a full list of actions:

Select an action in the GraphQL IDE

When creating a new entity

Like with the HTTP API, you must post a draft to create a new entity.

You must also include the values you want GraphQL to return once the entity has been created.

# Create a new entity
mutation CreateDiscountCode {
# The action for creating a Discount Code
createDiscountCode(
# The DiscountCodeDraft and its required fields
draft: {
code: "SAVE25"
isActive: true
cartDiscounts: { typeId: "cart-discount", id: "{cartDiscountID}" }
}
) {
# The values to return
code
isActive
}
}

When updating an existing entity

Like with the HTTP API, you must post an array of update actions to modify the data of existing entities.

You must also include the values you want GraphQL to return once the entity has been updated.

# Update an existing entity
mutation DeactivateDiscountCode {
# The action to update an existing entity
updateDiscountCode(
version: 1
id: "{discountCodeID}"
## Include update actions and their required parameters
actions: [{ changeIsActive: { isActive: false } }]
) {
# The values to return
code
isActive
}
}

Delete entities

When deleting entities within your Project, use mutation. You can include a name to describe the call.

# Delete an existing entity
mutation DeleteDiscountCode {
# The action to delete an existing entity
deleteDiscountCode(version: 1, id: "{discountCodeID}") {
# The values to return
id
code
}
}

Try our example calls

The following GraphQL calls demonstrate how to perform the same example calls as in the Manage Customers and Manage Products pages as well as how to use Product Projection Search.

Manage Customers

Create a Customer

Example GraphQL request to create a Customergraphql
mutation CreateCustomer {
customerSignUp(
# Creating a Customer requires a CustomerDraft which has two required fields: email and password.
draft: { email: "graphql@example.com", password: "examplePassword" }
) {
customer {
# Return the new Customer's ID, version, and email address.
id
version
email
}
}
}
Returned Customer resourcejson
{
"data": {
"customerSignUp": {
"customer": {
"id": "{customerID}",
"version": 1,
"email": "graphql@example.com"
}
}
}
}

Query a Customer

Example GraphQL request to query a Customergraphql
query GetCustomerById {
# Access the Customer's endpoint based on their ID.
customer(id: "{customerID}") {
# Return the Customer's ID, version, email, and name.
id
version
email
}
}
Returned Customer resourcejson
{
"data": {
"customer": {
"id": "{customerID}",
"version": 1,
"email": "graphql@example.com"
}
}
}

Add a Customer name

Example GraphQL request to update a Customergraphql
mutation AddCustomerName {
# The update action
updateCustomer(
# The current version of the Customer. This is 1 for new Customers.
version: 1
# The ID of the Customer to update.
id: "{customerID}"
# An array of update actions.
actions: [
{
# The action to change the first name.
setFirstName: { firstName: "John" }
}
{
# The action to change the last name.
setLastName: { lastName: "Smith" }
}
]
) {
# Return the ID, version, email address, and name of the Customer.
id
version
email
firstName
lastName
}
}
Returned Customer resourcejson
{
"data": {
"updateCustomer": {
"id": "{customerID}",
"version": 3,
"email": "graphql@example.com",
"firstName": "John",
"lastName": "Smith"
}
}
}

Find a Customer by their email address

Example GraphQL request to find a Customer by their email addressgraphql
query GetCustomerByEmail {
# Access the Customers endpoint, filtering results by the "where" query parameter.
customers(where: "email=\"graphql@example.com\"") {
results {
# Return the Customer's ID, version, email, and name.
id
version
email
firstName
lastName
}
}
}
Returned Customer resourcejson
{
"data": {
"customers": {
"results": [
{
"id": "{customerID}",
"version": 3,
"email": "graphql@example.com",
"firstName": "John",
"lastName": "Smith"
}
]
}
}
}

Manage Products

Create a ProductType

Example GraphQL request to create a Product Typegraphql
mutation CreateProductType {
createProductType(
# Creating a Product Type requires a ProductTypeDraft which has two required fields: name and description.
draft: {
name: "A new Product Type"
description: "Description of the new Product Type"
}
) {
# Return the new Product Type's ID, version, name, and description.
id
version
name
description
}
}
Returned Product Type resourcejson
{
"data": {
"createProductType": {
"id": "{productTypeID}",
"version": 1,
"name": "A new Product Type",
"description": "Description of the new Product Type"
}
}
}

Create a Product

Example GraphQL request to create a Productgraphql
mutation CreateProduct {
createProduct(
draft: {
# Creating a Product requires a ProductDraft which has three required fields: name, productType, and slug.
name: { locale: "en", value: "English Product Name" }
productType: { typeId: "product-type", id: "{productTypeID}" }
slug: { locale: "en", value: "english-product-name" }
}
) {
# Return the new Product's id, Product Type, version, and published ("current") name.
id
productType {
id
}
version
masterData {
current {
nameAllLocales {
value
}
}
}
}
}
Returned Product resourcejson
{
"data": {
"createProduct": {
"id": "{productID}",
"productType": {
"id": "{productTypeID}"
},
"version": 1,
"masterData": {
"current": {
"nameAllLocales": [
{
"value": "English Product Name"
}
]
}
}
}
}
}

Query your Product

Example GraphQL request to query a Productgraphql
query QueryProduct {
# Access the Product endpoint based on its ID.
product(id: "{productID}") {
# Return the Product's ID, version, and published ("current") name.
id
version
masterData {
current {
nameAllLocales {
value
}
}
}
}
}
Returned Product resourcejson
{
"data": {
"product": {
"id": "{productID}",
"version": 1,
"masterData": {
"current": {
"nameAllLocales": [
{
"value": "{productName}"
}
]
}
}
}
}
}

Create a ProductVariant

Example GraphQL request to create a Product Variantgraphql
mutation AddProductVariant {
# The update action
updateProduct(
# The current version of the Product. This is 1 for new Products.
version: 1
# The ID of the Product to add the Variant to.
id: "{productID}"
# An array of update actions
actions: [
{
# The action to add a Variant
addVariant: {
sku: "myProductVariantSKU"
key: "my-product-variant-key"
# This field is optional. If false it makes the Variant published ("current").
staged: false
}
}
]
) {
# Return the ID, version, and key and SKU of all the published ("current") Product Variants
id
version
masterData {
current {
allVariants {
key
sku
}
}
}
}
}
Returned Product resourcejson
{
"data": {
"updateProduct": {
"id": "{productID}",
"version": 3,
"masterData": {
"current": {
"allVariants": [
{
"key": "my-product-variant-key",
"sku": "myProductVariantSKU"
}
]
}
}
}
}
}

Retrieve values of enum Attributes in a ProductType

Example GraphQL request to retrieve values of enum Attributesgraphql
{
productType(key: "product-type-key") {
attributeDefinitions {
results {
name
type {
name
__typename
...enumValues
...localizedEnumValues
}
}
}
}
}
fragment enumValues on EnumAttributeDefinitionType {
values {
results {
key
label
}
}
}
fragment localizedEnumValues on LocalizableEnumAttributeDefinitionType {
values {
results {
key
labelAllLocales {
locale
value
}
}
}
}
Returned Product Type Attribute valuesjson
{
"data": {
"productType": {
"attributeDefinitions": {
"results": [
{
"name": "creationDate",
"type": {
"name": "datetime",
"__typename": "DateTimeAttributeDefinitionType"
}
},
{
"name": "articleNumberManufacturer",
"type": {
"name": "text",
"__typename": "TextAttributeDefinitionType"
}
},
{
"name": "madeInItaly",
"type": {
"name": "enum",
"__typename": "EnumAttributeDefinitionType",
"values": {
"results": [
{
"key": "yes",
"label": "yes"
},
{
"key": "no",
"label": "no"
}
]
}
}
},
{
"name": "color",
"type": {
"name": "lenum",
"__typename": "LocalizableEnumAttributeDefinitionType",
"values": {
"results": [
{
"key": "black",
"labelAllLocales": [
{
"locale": "en",
"value": "black"
},
{
"locale": "de",
"value": "schwarz"
}
]
},
{
"key": "white",
"labelAllLocales": [
{
"locale": "de",
"value": "weiss"
},
{
"locale": "en",
"value": "white"
}
]
}
]
}
}
}
]
}
}
}
}

Search based on text and locale

Example GraphQL request to search using text and localegraphql
query {
productProjectionSearch(staged: true, locale: "en-US", text: "bed") {
total
# Uncomment to return the ID and English name of each result.
# results{
# id
# name(locale:"en-US")
# }
}
}
Returned Product Projection Search requestjson
{
"data": {
"productProjectionSearch": {
"total": 17
}
}
}

Search based on text, locale, and filtering

Example GraphQL request to search using text, locale, and filteringgraphql
query {
productProjectionSearch(
queryFilters: [{ string: "published:true" }]
staged: true
locale: "en-US"
text: "bed"
) {
# Return the total number of results.
total
# Uncomment to return the ID and English name of each result.
# results{
# id
# name(locale:"en-US")
# }
}
}
Returned Product Projection Search requestjson
{
"data": {
"productProjectionSearch": {
"total": 17
}
}
}

Search using filters

Example GraphQL request to search using filtersgraphql
query {
productProjectionSearch(
staged: true
filters: [
{
model: {
value: { path: "variants.price.centAmount", values: ["1599"] }
}
}
]
) {
total
results {
id
version
}
}
}
Returned Product Projection Search requestjson
{
"data": {
"productProjectionSearch": {
"total": 3,
"results": [
{
"id": "394f20b4-0b21-45f7-81cc-43a4e45ba775",
"version": 1
},
{
"id": "ecc60e5f-ddd7-4137-8b84-fcaa17426549",
"version": 3
},
{
"id": "df65a374-e281-41a1-a370-c4d2591cae39",
"version": 1
}
]
}
}
}

Retrieve facet calculation

Example GraphQL request to retrieve facet calculationgraphql
query {
productProjectionSearch(
facets: [
{
model: {
range: {
path: "variants.price.centAmount"
ranges: [{ from: "1000", to: "3000" }]
countProducts: false
}
}
}
]
) {
facets {
facet
value {
type
... on RangeFacetResult {
dataType
ranges {
type
... on RangeCountDouble {
from
fromStr
to
toStr
count
productCount
totalCount
total
min
max
mean
}
}
}
}
}
}
}
Returned Product Projection Search requestjson
{
"data": {
"productProjectionSearch": {
"facets": [
{
"facet": "variants.price.centAmount",
"value": {
"type": "range",
"dataType": "number",
"ranges": [
{
"type": "double",
"from": 1000,
"fromStr": "1000.0",
"to": 3000,
"toStr": "3000.0",
"count": 35,
"productCount": null,
"totalCount": 35,
"total": 62065,
"min": 1099,
"max": 2999,
"mean": 1773.2857142857142
}
]
}
}
]
}
}
}

Differentiate between highPrecision and centPrecision money

Example GraphQL request to query for highPrecision and centPrecision moneygraphql
{
productProjectionSearch(staged: false, locale: "en", text: "blue") {
count
results {
id
masterVariant {
sku
prices {
...productPrice
}
}
}
}
}
fragment productPrice on ProductPriceSearch {
value {
...money
__typename
}
discounted {
value {
...money
__typename
}
__typename
}
}
fragment money on BaseMoney {
type
currencyCode
centAmount
fractionDigits
... on HighPrecisionMoney {
preciseAmount
}
}
Returned Product Projection Search requestjson
{
"data": {
"productProjectionSearch": {
"results": [
{
"id": "500797c7-e719-4d72-8c69-92fdee39d451",
"masterVariant": {
"sku": "M0E20000000E582",
"prices": [
{
"value": {
"type": "highPrecision",
"currencyCode": "USD",
"centAmount": 24875,
"fractionDigits": 11,
"preciseAmount": 24875123456789,
"__typename": "HighPrecisionMoney"
},
"discounted": null
},
{
"value": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 16311,
"fractionDigits": 2,
"__typename": "Money"
},
"discounted": null
}
]
}
}
]
}
}
}