# Designing Mutations — GraphQL

Source: https://www.skillbyai.com/en/graphql/m-design

> Input and payload types.

## Specific actions, single input, rich payload

Name mutations after **business actions** (`placeOrder`, `cancelSubscription`) rather than generic `updateOrder` with many optional fields. A common convention uses a single **input** argument and returns a **payload** type containing the changed objects (so clients can update their caches) and any user-facing errors. Make mutations idempotent where possible, for example by accepting a client-generated ID or idempotency key for operations such as payments.

## Changing data and reporting problems

Well-designed mutations, clear error handling and real-time subscriptions complete the API.

![Three ideas: mutation design, error handling, subscriptions.](assets/figures/graphql/section-4-map.svg) — Figure 4.1 — Mutations, errors and subscriptions.

## A placeOrder mutation

Schema and a client operation.

```graphql
input PlaceOrderInput {
  cartId: ID!
  shippingAddressId: ID!
  idempotencyKey: String!
}

type PlaceOrderPayload {
  order: Order
  userErrors: [UserError!]!
}

type UserError {
  field: [String!]
  message: String!
  code: String!
}

mutation Checkout($input: PlaceOrderInput!) {
  placeOrder(input: $input) {
    order { id status total { amount currency } }
    userErrors { field message code }
  }
}
```

## Return what changed

Including the updated object with its id lets normalised client caches refresh automatically.

**Quiz:** Why return the modified object in a mutation payload?

- [x] So clients can update their caches without another request
- [ ] Because GraphQL requires exactly one field
- [ ] To slow down attackers
- [ ] To avoid using variables

*Answer:* So clients can update their caches without another request. Caches normalise by id.
