Create an advanced GraphQL query

Learn how to query Composable Commerce with GraphQL to find out Project information.

  • After completing this page, you should be able to:

    • Identify the correct usage of GraphQL to find out Project information and use reference expansion.
  • Besides providing support for all CRUD (create, update, delete) operations to manage resources in a Composable Commerce Project, GraphQL provides additional features, such as the possibility to monitor the health of your Project and even automate processes.

    Use GraphQL for fetching information about Project limits

    Composable Commerce provides the ability through GraphQL to access information about your Project, including what limits exist and in some cases what the current count of a resource is. For example, you can query the limit of the number of Customers you can have in your Project as well as how many you currently have.

    You can also query other Project information like the name and key.

    This is an example of using one query to find both Project information such as the key, name, and trial end date, as well as the limit and usage information of multiple resources:

    query projectInfoAndLimits {
    project {
    key
    name
    version
    trialUntil
    carts {
    deleteDaysAfterLastModification
    }
    }
    limits {
    customers {
    total {
    limit
    current
    }
    }
    carts {
    total {
    limit
    current
    }
    }
    productDiscounts {
    totalActive {
    limit
    current
    }
    }
    cartDiscounts {
    totalActiveWithoutDiscountCodes {
    limit
    current
    }
    }
    productType {
    total {
    limit
    current
    }
    }
    query {
    offset {
    limit
    }
    }
    stores {
    total {
    limit
    current
    }
    productSelections {
    limit
    }
    productDistributionChannels {
    limit
    }
    inventorySupplyChannels {
    limit
    }
    }
    }
    }

    This would generate a response as follows:

    {
    "data": {
    "project": {
    "key": "graphql",
    "name": "graphQL",
    "version": 10,
    "trialUntil": "2024-03",
    "carts": {
    "deleteDaysAfterLastModification": 90
    }
    },
    "limits": {
    "customers": {
    "total": {
    "limit": 10000000,
    "current": 6
    }
    },
    "carts": {
    "total": {
    "limit": 10000000,
    "current": 5
    }
    },
    "productDiscounts": {
    "totalActive": {
    "limit": 500,
    "current": 2
    }
    },
    "cartDiscounts": {
    "totalActiveWithoutDiscountCodes": {
    "limit": 100,
    "current": 1
    }
    },
    "productType": {
    "total": {
    "limit": 1000,
    "current": 3
    }
    },
    "query": {
    "offset": {
    "limit": 10000
    }
    },
    "stores": {
    "total": {
    "limit": 300000,
    "current": 1
    },
    "productSelections": {
    "limit": 100
    },
    "productDistributionChannels": {
    "limit": 100
    },
    "inventorySupplyChannels": {
    "limit": 100
    }
    }
    }
    }
    }

    This feature is a great way to get a quick snapshot of the health of your Project.

    Use Reference Expansion

    In Composable Commerce, resources often have references to other resources. For example, a Product has a reference to the Product Type that it is based on, Customer can have a reference to a Customer Group that they belong to, and an Order that was created from a Cart has a reference to that Cart.

    An important point to remember is that when you expand a reference, Composable Commerce will make a second database request to get that information. That reference is done in series with the primary information retrieval, and so it adds to the query complexity and to the overall time in servicing the request. This is true whether you use reference expansion in REST or GraphQL.

    What does a reference look like? Two kinds of references exist-key references and id references. Only id references are expandable. An id reference has two parts. The first part is a string that is the typeId. This would be the string cart for a Cart reference or product-type for a Product Type reference and so on. The second part is the id itself which is the Composable Commerce generated identifier, for example cc1fc167-bb22-46ea-81b2-9c23a72cdda7.

    Composable Commerce provides two reference fields: the reference itself and the referenced object. You can select either or both to include in the returned JSON, such as choosing to retrieve both the id and the typeId depending on your requirements.

    Here’s an example request for both of those fields from an Order:

    query queryOrdersWithRef {
    order(id: "{id}") {
    customerId
    customerEmail
    cartRef {
    typeId
    id
    }
    cart {
    customerEmail
    country
    cartState
    }
    }
    }

    You can see the return items cartRef, which has the typeId and id, and the cart, which is the expanded reference where we request the customerEmail, country, and cartState.

    An example response would be:

    {
    "data": {
    "order": {
    "customerId": "eaf18adc-c61e-4f2c-9d04-b6b8ad51d998",
    "customerEmail": "jane.doe@example.com",
    "cartRef": {
    "typeId": "cart",
    "id": "93e5f3dc-43d0-480a-a0db-9e0932b1920e"
    },
    "cart": {
    "customerEmail": "jane.doe@example.com",
    "country": "GB",
    "cartState": "Ordered"
    }
    }
    }
    }

    While you can also request reference fields to be expanded in the REST API, it works differently. We will look into that in the next section.

    Keep in mind that expanding a reference, either in GraphQL or the REST API, requires additional database access and therefore increases your query complexity.

    Use introspection

    GraphQL provides a strict specification that allows for introspection. This means that you can query a GraphQL schema to find out information about the elements in it. This powerful feature helps with the development of tools that can generate GraphQL queries, even without prior knowledge of the available elements.

    You can query to find all of the types that are available or, as in the following example, you can query to find all of the fields that are available for a type—in our case, for Customer.

    query QueryCustomerSchema {
    __type(name: "Customer") {
    name
    fields {
    name
    type {
    name
    kind
    ofType {
    name
    kind
    }
    }
    }
    }
    }

    Which returns the following (this has been truncated for brevity):

    {
    "data": {
    "__type": {
    "name": "Customer",
    "fields": [
    {
    "name": "customerNumber",
    "type": {
    "name": "String",
    "kind": "SCALAR",
    "ofType": null
    }
    },
    {
    "name": "email",
    "type": {
    "name": null,
    "kind": "NON_NULL",
    "ofType": {
    "name": "String",
    "kind": "SCALAR"
    }
    }
    },
    {
    "name": "addresses",
    "type": {
    "name": null,
    "kind": "NON_NULL",
    "ofType": {
    "name": null,
    "kind": "LIST"
    }
    }
    },
    {
    "name": "defaultShippingAddressId",
    "type": {
    "name": "String",
    "kind": "SCALAR",
    "ofType": null
    }
    },

    Test your knowledge