🖋 GraphQL operations
So far, our app has only used one type of GraphQL operation: queries. These are read-only operations to retrieve data. To modify data, we need to use another type of GraphQL operation: mutations, which are write operations.
Much like the Query
type, the Mutation
type serves as an entry point to our schema. It follows the same syntax as the schema definition language, or SDL, that we've been using so far.
✍️ Schema syntax
We declare the Mutation
type using the type
keyword, then the name Mutation
. Inside the curly braces, we have our entry points, the fields we'll be using to mutate our data.
We recommend starting with a verb that describes the specific action of our update operation (such as add
, delete
, or create
), followed by whatever data the mutation acts on. Because mutations typically modify a specific object, they often require arguments. We can add arguments as needed, following the same SDL syntax. The return type of the mutation comes after the colon.
For the mutation response, we should return the data that the mutation updated, so that our client can update its UI without having to run a followup query.
🤔 Modifying multiple objects
When a mutation updates more than just one object, how do we pick which one to return?
To answer that question, let's look at an example schema with spacecats and missions.
A spacecat has a list of missions they've been assigned to. A mission can also have more than one spacecat assigned to it, like a crew. We want to create a mutation called assignMission
that assigns one spacecat to a particular mission. This would update that spacecat's list of missions, and it would also update a mission's list of crew members.
So which type should our mutation return? SpaceCat
? Or Mission
?
We'll want to return both, because our client might need both.
In addition, we'll need to account for any partial errors that might occur and return helpful information to the client. We recommend adding three common fields to all mutation responses:
code
: anInt
that refers to the status of the response, similar to an HTTP status code.success
: aBoolean
flag that indicates whether all the updates the mutation was responsible for succeeded.message
: aString
to display information about the result of the mutation on the client side. This is particularly useful if the mutation was only partially successful and a generic error message can't tell the whole story.
Circling back to the assignMission
mutation, we're going to create a new type specifically for its response. By convention, this return type will start with the name of the mutation (AssignMission
) and end with Response
. This type will contain the three informational properties, as well as additional fields for each object that the mutation updated.
Query
fields, fields of the Drag items from this box to the blanks above
retrieve
search
entry points
modify
create
delete
assignments
Mutation
operations
write
read
endpoints
That's the basics of what we need to know about mutations! Let's dive into the code and add our first mutation to the schema.
Share your questions and comments about this lesson
Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.
You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.