# graphql

Executes queries and mutations against Shopify's GraphQL Admin API. The response is stored in a variable for further processing.

```liquid
{% graphql query: product_query, variables: my_variables as result %}

{% if result.product %}
  {% log result.product.title %}
{% endif %}
```

#### Syntax

```liquid
{% graphql query: query_string, variables: variables_object as result_variable %}
```

#### Parameters

| Parameter   | Required | Description                                           |
| ----------- | -------- | ----------------------------------------------------- |
| `query`     | Yes      | GraphQL query or mutation string                      |
| `variables` | No       | Object containing variables for the GraphQL operation |

#### Result Object

The result contains the returned data directly accessible at the top level. Query fields are available as properties on the result variable.

Example query:

```liquid
{% graphql query: product_query, variables: vars as result %}
{% comment %} Access result.product directly, not result.data.product {% endcomment %}
```

If errors occur, they are available in the `errors` property:

| Property | Type       | Description                                    |
| -------- | ---------- | ---------------------------------------------- |
| `errors` | array/null | Array of error objects if the operation failed |

Example result for a product query:

```json
{
  "product": {
    "id": "gid://shopify/Product/123",
    "title": "Example Product"
  }
}
```

#### Examples

**Basic product query:**

```liquid
{% capture query %}
  query getProduct($id: ID!) {
    product(id: $id) {
      id
      title
      handle
      status
    }
  }
{% endcapture %}

{% json variables %}
  {
    "id": "gid://shopify/Product/{{ product_id }}"
  }
{% endjson %}

{% graphql query: query, variables: variables as result %}

{% if result.product %}
  {% log "Product title:" %}
  {% log result.product.title %}
{% endif %}
```

**Update product with mutation:**

```liquid
{% capture mutation %}
  mutation updateProduct($input: ProductInput!) {
    productUpdate(input: $input) {
      product {
        id
        title
      }
      userErrors {
        field
        message
      }
    }
  }
{% endcapture %}

{% json variables %}
  {
    "input": {
      "id": "gid://shopify/Product/{{ product_id }}",
      "title": "{{ new_title }}"
    }
  }
{% endjson %}

{% graphql query: mutation, variables: variables as result %}

{% if result.productUpdate.userErrors.size > 0 %}
  {% for error in result.productUpdate.userErrors %}
    {% log error.message %}
  {% endfor %}
{% else %}
  {% log "Product updated successfully" %}
{% endif %}
```

**Paginated query with cursor:**

```liquid
{% capture query %}
  query getCustomers($cursor: String, $query: String) {
    customers(first: 50, after: $cursor, query: $query) {
      edges {
        node {
          id
          email
          firstName
          lastName
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
{% endcapture %}

{% assign cursor = null %}
{% assign all_customers = "" | split: "" %}

{% for i in (1..100) %}
  {% json variables %}
    {
      "cursor": {{ cursor | json }},
      "query": "tag:vip"
    }
  {% endjson %}

  {% graphql query: query, variables: variables as result %}

  {% for edge in result.customers.edges %}
    {% assign all_customers = all_customers | push: edge.node %}
  {% endfor %}

  {% if result.customers.pageInfo.hasNextPage %}
    {% assign cursor = result.customers.pageInfo.endCursor %}
  {% else %}
    {% break %}
  {% endif %}
{% endfor %}

{% log "Total customers found: " | append: all_customers.size %}
```

**Query with dynamic variables:**

```liquid
{% capture query %}
  query getOrder($id: ID!) {
    order(id: $id) {
      id
      name
      totalPriceSet {
        shopMoney {
          amount
          currencyCode
        }
      }
      lineItems(first: 50) {
        edges {
          node {
            title
            quantity
          }
        }
      }
    }
  }
{% endcapture %}

{% assign order_gid = "gid://shopify/Order/" | append: order.id %}

{% json variables %}
  {
    "id": "{{ order_gid }}"
  }
{% endjson %}

{% graphql query: query, variables: variables as order_data %}

{% assign total = order_data.order.totalPriceSet.shopMoney.amount %}
{% log "Order total:" | append: total %}
```

**Handle errors gracefully:**

```liquid
{% capture query %}
  query getInventory($id: ID!) {
    inventoryItem(id: $id) {
      id
      tracked
      inventoryLevels(first: 10) {
        edges {
          node {
            available
            location {
              name
            }
          }
        }
      }
    }
  }
{% endcapture %}

{% json variables %}
  {
    "id": "gid://shopify/InventoryItem/{{ inventory_item_id }}"
  }
{% endjson %}

{% graphql query: query, variables: variables as result %}

{% if result.errors %}
  {% log "GraphQL error occurred:" %}
  {% for error in result.errors %}
    {% log error.message %}
  {% endfor %}
{% else %}
  {% for level in result.inventoryItem.inventoryLevels.edges %}
    {% log level.node.location.name %}
    {% log level.node.available %}
  {% endfor %}
{% endif %}
```

**Bulk operation query:**

```liquid
{% capture mutation %}
  mutation bulkOperationRunQuery($query: String!) {
    bulkOperationRunQuery(query: $query) {
      bulkOperation {
        id
        status
      }
      userErrors {
        field
        message
      }
    }
  }
{% endcapture %}

{% capture bulk_query %}
{
  products {
    edges {
      node {
        id
        title
        variants {
          edges {
            node {
              id
              sku
              inventoryQuantity
            }
          }
        }
      }
    }
  }
}
{% endcapture %}

{% json variables %}
  {
    "query": {{ bulk_query | json }}
  }
{% endjson %}

{% graphql query: mutation, variables: variables as result %}

{% if result.bulkOperationRunQuery.bulkOperation %}
  {% log "Bulk operation started:" %}
  {% log result.bulkOperationRunQuery.bulkOperation.id %}
{% endif %}
```

#### Notes

* Consumes 1 credit per operation
* Uses the store's API version configured in DataJet
* GraphQL errors are automatically logged to the script logs
* Variables must be a valid object (use `json` tag to construct complex variables)
* For large datasets, use pagination with cursors to avoid timeouts
* Result properties are accessed directly (e.g., `result.products`, not `result.data.products`)
* Refer to [Shopify's GraphQL Admin API documentation](https://shopify.dev/docs/api/admin-graphql) for available queries and mutations
