Contact Us 1-800-596-4880

Writing GraphQL Queries and Mutations in DataGraph

This brief tutorial introduces key concepts for writing GraphQL queries in Anypoint DataGraph.

Learn how to use the Anypoint DataGraph query editor to:

  1. Discover and add a query operation

  2. Add input parameters to a query

  3. Discover which fields are available to query

  4. Add nested types

  5. Add a query alias

  6. Write a mutation and understand query types

Discover and Add a Query Operation

In GraphQL, query methods serve as the entry points to retrieve the data you want. Start by using the schema explorer in the Anypoint DataGraph query editor to discover which query methods are available for an API schema.

For example, the Catalyst Order API schema, used in the DataGraph quick start guide, has two query methods associated with it: ordersCustomerByCustomerId and ordersByOrderId:

Two query methods listed in the schema explorer

Consider ordersByOrderId: This query method returns data about the object type OrderResponse and requires an argument for orderID in the form of a string:

ordersByOrderId (orderId:String!):OrderResponse

In GraphQL, you add the query method to start a query:

{
  ordersByOrderId(orderId:String!)
}

Add Input Parameters

Notice that the input parameter for the query method orderID is a non-nullable field, as indicated by the exclamation point (!). This field requires a string data type that is not a null value.

In this case, you need to add an order ID to the query:

{
  ordersByOrderId(orderId: "51c0ba3a-7e64-11e7-bb31-be2e44b06b3")
}

Add Fields

Fields represent a type’s dataset that is returned in a query response, and you can choose whatever fields you need when writing a query. For example, as previously mentioned, the ordersByOrderID query method returns the OrderResponse object type, which returns the following fields:

Available fields listed in the schema explorer

As you write a query, you can add or remove any of these fields. The following query a uses some of the available fields:

{
  ordersByOrderId(orderId: "51c0ba3a-7e64-11e7-bb31-be2e44b06b3") {
    customerId
    status
    subtotal
    taxPrice
    total
    trackingNumber
  }
}

OrderResponse is a Level-1 type, meaning you can access it directly with a query method, as in the previous example.

Add Fields for Nested Types

Many of the fields returned by the OrderResponse object type, such as billingAddress, are object types themselves that contain additional data that can make your query result more valuable. These additional types are known as nested types.

The billingAddress object type returns the PostalAddress object type, which itself returns several additional fields. To query billingAddress, you must specify which fields to return from PostalAddress. For example:

{
  ordersByOrderId(orderId: "51c0ba3a-7e64-11e7-bb31-be2e44b06b3") {
    billingAddress {
      state
      city
      postalCode
    }
  }
}

As a result, your final query looks like:

{
  ordersByOrderId(orderId: "51c0ba3a-7e64-11e7-bb31-be2e44b06b3") {
    customerId
    status
    subtotal
    taxPrice
    total
    trackingNumber
    billingAddress {
      state
      city
      postalCode
    }
  }
}

For this query, Anypoint DataGraph returns:

{
  "data": {
    "ordersByOrderId": {
      "customerId": "1964401a-a8b3-40c1-b86e-d8b9f75b5842",
      "status": "Draft",
      "subtotal": "100.21",
      "taxPrice": "15.22",
      "total": "125.43",
      "trackingNumber": "",
      "billingAddress": {
        "state": "CA",
        "city": "San Francisco",
        "postalCode": "94210"
      }
    }
  }
}

Add a Query Alias

You can use aliases to rename individual keys in the query response.

For example, you can rename the total field to totalPrice and the status field to orderStatus in only your query response.

{
  ordersByOrderId(orderId: "51c0ba3a-7e64-11e7-bb31-be2e44b06b3") {
    billingAddress {
      state
      city
      postalCode
    }
    totalPrice : total
    orderStatus : status
  }
}

If you want to get the same fields for two or more query operations using different input parameters, you can provide an alias to the query operations.

{
  Order1: ordersByOrderId(orderId: "51c0ba3a-7e64-11e7-bb31-be2e44b06b3") {
    billingAddress {
      state
      city
      postalCode
    }
    totalPrice : total
    orderStatus : status
  }

  Order2: ordersByOrderId(orderId: "87c0ba4a-de28-12o7-pd11-eew12094b0w4) {
    billingAddress {
      state
      city
      postalCode
    }
    totalPrice : total
    orderStatus : status
  }
}

This helps to avoid errors if the same fields get different values.

Write a Mutation

Mutations are operations you use to add, update, and delete data objects. In GraphQL, mutation operations represent the POST, PUT, PATCH, and DELETE HTTP methods you’ve defined in your REST API specification.

To simplify the schema, inputs to mutations are handled by input types, which represent the attributes of objects created by mutation operations. Input types are POST, PUT, and DELETE request objects you use to modify information in your unified schema when you run mutations.

For example, the schema shown in the following example has six mutation operations associated with it:

Six mutation operations listed in the schema explorer

Consider createCustomer: This mutation takes the CustomerInput object as an input and creates a new object of type Customer.

So in this case, the input type CustomerInput has the following fields:

Fields for CustomerInput listed in the schema explorer

Notice that the address field has data from the AddressInput input type:

Fields for AddressInput listed in the schema explorer

As you execute the mutation operation, you provide a value for each field in the input type:

mutation {
  createCustomer(input: {
    firstName: "Lydia",
    lastName: "Millet",
    address: {
      city: "Tucson",
      state: "Arizona",
      street: "Speedway",
      postalCode: "1234"
    }
  })
  {
    id
  }
}

Because this mutation creates a new customer, DataGraph returns the following:

{
  "data": {
    "createCustomer": {
      "id": 42
    }
  }
}

Note that the CustomerInput input type does not have an id field, so the mutation doesn’t include that field in the input to the mutation. However, the Customer type includes an id field, the value of which is generated based on the values provided in the input.