Launch Apollo Studio

Mutations in Apollo Kotlin


Mutations are GraphQL operations that modify back-end data. As a convention in GraphQL, queries are read operations and mutations are write operations.

Defining a mutation

You define a mutation in your app just like you define a query, except you use the mutation keyword. Here's an example mutation for upvoting a post:

UpvotePost.graphql
mutation UpvotePost($postId: Int!) {
  upvotePost(postId: $postId) {
    id
    votes
  }
}

And here's an example schema snippet that supports this mutation:

schema.graphql
type Mutation {
  upvotePost(postId: Int!): Post
}

type Post {
  id: Int!
  votes: Int!
  content: String!
}

The fields of the Mutation type (such as upvotePost above) usually describe the actions that your mutations can take. These fields commonly take one or more arguments, because they help specify the data to create or modify.

Mutation return types

The return type of a Mutation field usually includes the back-end data that's been modified. This enables the requesting client to immediately know about the result of the mutation.

In the example above, upvotePost returns the Post object that's just been upvoted. Here's an example response:

{
  "data": {
    "upvotePost": {
      "id": "123",
      "votes": 5
    }
  }
}

For more information on mutation return types, see Designing mutations.

Generating mutation classes

Similar to queries, mutations are represented by instances of generated classes, conforming to the Mutation interface. Constructor arguments are used to define mutation variables. You pass a mutation object to ApolloClient#mutation(mutation) to send the mutation to the server, execute it, and receive typed results:

val upvotePostMutation = UpvotePostMutation(votes = 3)

val response = try {
  apolloClient.mutation(upvotePostMutation).execute()
} catch(e: ApolloException) {
  // handle error
}

Using fragments in mutation results

In many cases, you'll want to use mutation results to update your UI. Fragments are a great way to share result handling between queries and mutations:

mutation UpvotePost($postId: Int!) {
  upvotePost(postId: $postId) {
    ...PostDetails
  }
}

Passing input objects

The GraphQL type system includes input objects as a way to pass complex values to fields. Input objects are often used for mutation variables, because they give you a compact way to pass in objects to be created:

mutation CreateReviewForEpisode($episode: Episode!, $review: ReviewInput!) {
  createReview(episode: $episode, review: $review) {
    stars
    commentary
  }
}
val reviewInput = ReviewInput(stars = 5, commentary = "This is a great movie!")

try {
  val response = apolloClient.mutation(CreateReviewForEpisodeMutation(episode = Episode.NEWHOPE, review = reviewInput)).execute()
} catch (e: ApolloException) {
  // handle exception
}
Edit on GitHub