蜜豆视频

Mutations

This is part 3 of the series for GraphQL and 蜜豆视频 Commerce. Mutations are the ability to save, update, and return values using GraphQL.

video poster

Transcript
The GraphQL specification is written with the expectation that you will use API requests not only to query data, but also to write data. So to look at an example of that, unlike with REST where the distinction between data changing requests and non-data changing requests is done with the convention of HTTP verbs, with GraphQL, basically what I have here looks the same as a query and is going to the same endpoint on my backend, but is distinguished with this keyword, mutation. So that is what tells GraphQL that I do expect that what I鈥檓 passing in here is a mutation and not a query. So this example is another example from 蜜豆视频 Commerce, and the key thing to note is that the syntax is basically identical to a query. So this is the addProductsToCart mutation that adds items to a pre-existing cart I have in a session. And just like the query syntax that we saw, this accepts input arguments right here for the input that I want to give. I鈥檓 wrapping this and passing variable placeholders into those arguments just like we saw with a query. And also, just like with a query, I am expressing the fields that I want returned in the data. So in addition to making the changes to data on the backend, this will also return a certain type of data, and I can express what I want to get back in that returned data just like I did with a query. So I am passing in with this a variables dictionary matching the variables in my wrapper with a cart ID that I used a previous mutation to generate, to generate an empty cart, and then an array of information about the items that I want to add to my cart, the quantity and the skew. And if I send that, the data returned pretty much looks like we saw in a query. Just matching the sub-selection that I expressed here in my syntax, I鈥檓 getting back the updated information about my cart. The total quantity in my cart and the grand total. And I could update my sub-selection there to include all kinds of details about the updated cart depending on what my needs are for updating information in my application based on that mutation that I just did.

Example mutation

Any complete API specification needs to offer the ability not only to query data, but also to create and update it.

REST distinguishes between requests that change data and those that do not with the request type or 鈥渧erb鈥 (GET vs. POST or PUT).
When using GraphQL, data-modifying queries are distinguished by the mutation keyword that corresponds with a different
root type in the schema defined at the server.

Look at this example mutation for adding a product to a user鈥檚 cart. (This requires a cart ID that was generated
for the logged-in customer鈥檚 session or using the createEmptyCart mutation.)

mutation doAddToCart(
    $cartId: String!,
    $cartItems: [CartItemInput!]!
) {
    addProductsToCart(
        cartId: $cartId
        cartItems: $cartItems
    ) {
        cart {
            total_quantity
            prices {
                grand_total {
                    value
                }
            }
        }
    }
}

You can imagine the above mutation being sent in a request along with the following variables dictionary:

{
  "cartId": "{cart-id}",
  "cartItems": [
    {
      "quantity": 1,
      "sku": "VT01-RN-XS"
    }
  ]
}

And finally, you might receive a response like this:

{
  "data": {
    "addProductsToCart": {
      "cart": {
        "total_quantity": 1,
        "prices": {
          "grand_total": {
            "value": 35.2
          }
        }
      }
    }
  }
}

The chief thing to note that about the above example is that, apart from the use of the mutation keyword instead of query,
the syntax is identical to a query. Like queries, the mutation includes:

  • An arbitrary operation name (doAddToCart)
  • A list of variables (for example, $cartId)
  • An initial field (addProductsToCart) with arguments (for example, cartId, set to the value of $cartId) in parentheses
  • A subselection of fields in braces

The fields subselection allows you to flexibly define the fields you would like returned (from the type assigned as the
return value of addProductsToCart - AddProductsToCartOutput) after the mutation is completed.

As explained previously, fields defined in a GraphQL schema start on a root type for queries (typically referred to as a Query). Similarly,
another root type exists for mutations (typically referred to as Mutation). addProductsToCart is a field
on that root type.

A few other notes about the above example:

  • The ! character suffixing String and CartItemInput indicates that the variable is required.
  • The square brackets ([]) around the CartItemInput type specified for $cartItems indicate a list
    of that type rather than a single value.

Useful GraphQL resources

recommendation-more-help
3a5f7e19-f383-4af8-8983-d01154c1402f