Docs
Launch GraphOS Studio
You're viewing documentation for a previous version of this software. Switch to the latest stable version.

Mutations


Queries are useful to fetch data from a server, but client-server communication may also require sending data to the server. This is where become handy. Just like REST, any request might end up causing some side-effects on the server, but by convention it's suggested that one doesn't use GET requests to modify data. is similar - technically any could be implemented to cause a data write. However, it's useful to establish a convention that any that cause writes should be sent explicitly via a mutation.

Apollo Android handles . Mutations are similar to queries in syntax, the only difference being that you use the keyword mutation instead of query to indicate that the root on this are going to be performing writes to the backend.

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

represent two things in one string:

  1. The name with , upvotePost, which represents the actual to be done on the server
  2. The you want back from the result of the to update the client: { votes }

The above will upvote a post on the server. The result might be:

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

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

val upvotePostMutation = UpvotePostMutation(votes = 3)
apolloClient
.mutate(upvotePostMutation)
.enqueue(object: ApolloCall.Callback<UpvotePost.Data>() {
override fun onResponse(response: Response<UpvotePost.Data>) {
Log.i(TAG, response.toString());
}
override fun onFailure(e: ApolloException) {
Log.e(TAG, e.getMessage(), e);
}
}
)
UpvotePostMutation upvotePostMutation = UpvotePostMutation.builder()
.votes(3)
.build();
apolloClient
.mutate(upvotePostMutation)
.enqueue(
new ApolloCallback<>(new ApolloCall.Callback<UpvotePost.Data>() {
@Override public void onResponse(@NotNull Response<UpvotePost.Data> response) {
Log.i(TAG, response.toString());
}
@Override public void onFailure(@NotNull ApolloException e) {
Log.e(TAG, e.getMessage(), e);
}
});
);

Using fragments in mutation results

In many cases, you'll want to use results to update your UI. can be a great way of sharing result handling between queries and mutations:

mutation UpvotePost($postId: Int!) {
upvotePost(postId: $postId) {
...PostDetails
}
}
apolloClient
.mutate(upvotePostMutation)
.enqueue(object: ApolloCall.Callback<UpvotePost.Data>() {
override fun onFailure(e: ApolloException) {
Log.e(TAG, e.getMessage(), e);
}
override fun onResponse(response: Response<UpvotePost.Data>) {
Log.i(TAG, response.data.upvotePost.fragments.postDetails);
}
}
)
apolloClient
.mutate(upvotePostMutation)
.enqueue(
new ApolloCallback<>(new ApolloCall.Callback<UpvotePost.Data>() {
@Override public void onResponse(@NotNull Response<UpvotePost.Data> response) {
Log.i(TAG, response.data.upvotePost.fragments.postDetails);
}
@Override public void onFailure(@NotNull ApolloException e) {
Log.e(TAG, e.getMessage(), e);
}
})
);

Passing input objects

The includes

as a way to pass complex values to . Input objects are often defined as , 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!")
apolloClient.mutate(CreateReviewForEpisodeMutation(episode = Episode.NEWHOPE, review = reviewInput))
ReviewInput reviewInput = ReviewInput.Builder()
.stars(5)
.commentary("This is a great movie!")
.build()
apolloClient.mutate(CreateReviewForEpisodeMutation(Episode.NEWHOPE, reviewInput))

Designing mutation results

In , can return any type, and that type can be queried just like a regular GraphQL . So the question is - what type should a particular mutation return?

In most cases, the data available from a result should be the server developer's best guess of the data a client would need to understand what happened on the server. For example, a mutation that creates a new comment on a blog post might return the comment itself. A mutation that reorders an array might need to return the whole array.

Uploading files

Apollo Android supports file uploading over

.

You need to define this mapping in your build.gradle file.

apollo {
customTypeMapping = [
"Upload" : "com.apollographql.apollo.api.FileUpload"
]
}

Note1 You don't need to register custom type adapter for FileUpload.

Note2 While Apollo Android doesn't use reflection for regular , it does for file upload. If you're using Proguard/R8, you need to keep everything inheriting from InputType:

proguard-rules.pro
-keep class * implements com.apollographql.apollo.api.InputType { *; }

In this example, the uses custom type named Upload for file upload. Change it to match your .

Create .

mutation SingleUpload($file: Upload!) {
singleUpload(file: $file) {
id
path
filename
mimetype
}
}

Call your with mimetype and a valid file path.

mutationSingle = SingleUploadMutation(file = FileUpload.create("image/jpeg", "/my/image.jpg"))
mutationSingle = SingleUploadMutation.builder()
.file(FileuploadKt.create(FileUpload.Companion, "image/jpeg", "/my/image.jpg"))
.build();

If you don't have a File, you can also subclass FileUpload:

object upload : FileUpload(mimetype) {
override fun contentLength(): Long {
TODO("return contentLength here")
}
override fun fileName(): String? {
TODO("return fileName to use in the multipart request here")
}
override fun writeTo(sink: BufferedSink) {
TODO("write the data here")
}
}
FileUpload upload = new FileUpload(mimetype) {
@Override
public long contentLength() {
// return contentLength here
}
@Override
public String fileName() {
// return fileName to use in the multipart request here
}
@Override
public void writeTo(@NonNull BufferedSink sink) {
// write the data here
}
};
Previous
Queries
Next
Normalized cache
Edit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc.

Privacy Policy

Company