Odyssey

Lift-off IV: Mutations

Feature OverviewWhat is a mutation?Adding a mutation to our schemaUpdating our TrackAPI data sourceResolving a mutation successfullyResolving a mutation with errorsTesting a mutation in the ExplorerThe useMutation hookOur mutation in the browser
7. Testing a mutation in the Explorer
3m

🧑‍🔬 Testing our mutation

Now that we have our schema, data source, and resolvers set up with helpful mutation responses, let's get ready to test our mutation in the Apollo Sandbox Explorer.

Let's start up the server by opening up a new terminal window. Here we'll navigate to the server folder with cd server, and run npm start.

With our server running, let's connect to our graph which is running on http://localhost:4000.

First let's check out our schema by clicking on the Schema page on the left sidebar. Under the Reference tab, we can see that there's a new Mutation type listed: the incrementTrackViews field!

http://localhost:4000
Screenshot of the GraphOS Studio Schema Reference tab, displaying the new mutation incrementTrackViews

To open the incrementTrackViews mutation in the Explorer, let's click on the play icon to the right of the field's description.

This takes us to the Explorer page, with the sidebar open and ready for us to start building our first mutation.

http://localhost:4000
Screenshot of Explorer with an empty Operation panel, ready for us to start building our query

Click the plus button (⊕) beside incrementTrackViews to add it to our Operation panel. This pre-fills some information for us! The syntax should feel familiar because it's the same syntax we've seen so far with our queries, particularly in Lift-off III where we used arguments and variables.

mutation IncrementTrackViews($incrementTrackViewsId: ID!) {
incrementTrackViews(id: $incrementTrackViewsId) {
}
}

✍️ Building a GraphQL mutation

We start with the mutation keyword, and then the name of the operation (which the Explorer has named IncrementTrackViews for us). Inside the brackets, we've got a variable denoted by the $ symbol called incrementTrackViewsId, which is of type ID and required.

This variable is set in the Variables section below. Right now it's set to null, so let's change it to the same track ID we've been working with: c_0.

http://localhost:4000
Screenshot showing the Variables panel in Explorer with a populated track ID
{
"incrementTrackViewsId": "c_0"
}
When writing a GraphQL mutation, which keyword should it start with?
As a best practice when writing a GraphQL mutation, which should come immediately after the keyword from the previous question?

Back to the mutation in the Operation panel!

Inside the curly braces is where we list our mutation entry point: incrementTrackViews. It takes in an id argument, which we set to the variable incrementTrackViewsId, the same one we just set to c_0.

Now inside the second pair of curly braces we can start to add the fields available in our response object. These fields are in the sidebar, making it really easy to build this mutation by clicking on the plus button (⊕) button beside the field.

We want to see the code, the success boolean, the message, and the track object itself.

Inside the track object, we want the id and the numberOfViews. The number of views is what we're updating, so we want to see the newly updated value after the mutation is hopefully successful. The id will be used by our Apollo Client cache, which we'll cover a little later when we get to the frontend implementation.

http://localhost:4000
Screenshot showing the Operation panel in Explorer containing the completed mutation called IncrementTrackViews

The mutation operation should look like this:

mutation IncrementTrackViews($incrementTrackViewsId: ID!) {
incrementTrackViews(id: $incrementTrackViewsId) {
code
success
message
track {
id
numberOfViews
}
}
}

Let's go ahead and run it!

On the right-hand side you can see the fields we expected: code is 200, the success flag is true, the message says it was successful and we get our newly updated track back.

http://localhost:4000
Screenshot of the Explorer showing a successful response to the IncrementTrackViews mutation

When we run the mutation again and again, we can see that the number of views is going up!

In the successful mutation response, where are the values of code, success and message coming from?

Let's see what happens when we change the incrementTrackViewsId to our silly string "DOESNTEXIST".

{
"incrementTrackViewsId": "DOESNTEXIST"
}

When we run this mutation, we see the response has code 404, success is false, and the message says Could not find track with specified ID. The track is also set to null with no data available.

http://localhost:4000
Screenshot of the Explorer showing a 404 response to the IncrementTrackViews mutation
When the mutation fails, where are the values of code and message coming from in the response?

Our mutation looks great and it's doing what it's supposed to! It's time to jump over to client-land.

Previous
Next

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.

              resolvers

              A function that populates data for a particular field in a GraphQL schema. For example:

              const resolvers = {
              Query: {
              author(root, args, context, info) {
              return find(authors, { id: args.id });
              },
              },
              };
              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              Apollo Sandbox

              A part of GraphOS Studio focused on local development, available at https://studio.apollographql.com/sandbox. Apollo Sandbox does not require an Apollo account.

              graph

              A schema-based data model representing how different data elements interconnect and can be accessed.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              arguments

              A key-value pair associated with a particular schema field that lets operations pass data to that field's resolver.

              Argument values can be hardcoded as literal values (shown below for clarity) or provided via GraphQL variables (recommended).

              query GetHuman {
              human(id: "200") {
              name
              height(unit: "meters")
              }
              }
              variables

              A placeholder for dynamic values in an operation allowing parameterization and reusability in requests. Variables can be used to fill arguments or passed to directives.

              query GetUser($userId: ID!) {
              user(id: $userId) {
              firstName
              }
              }

              In the query above, userId is a variable. The variable and its type are declared in the operation signature, signified by a $. The type of variable is a non-nullable ID. A variable's type must match the type of any argument it's used for.

              operation

              A single query, mutation, or subscription that clients send to a GraphQL server to request or manipulate data.

              variable

              A placeholder for dynamic values in an operation allowing parameterization and reusability in requests. Variables can be used to fill arguments or passed to directives.

              query GetUser($userId: ID!) {
              user(id: $userId) {
              firstName
              }
              }

              In the query above, userId is a variable. The variable and its type are declared in the operation signature, signified by a $. The type of variable is a non-nullable ID. A variable's type must match the type of any argument it's used for.

              variable

              A placeholder for dynamic values in an operation allowing parameterization and reusability in requests. Variables can be used to fill arguments or passed to directives.

              query GetUser($userId: ID!) {
              user(id: $userId) {
              firstName
              }
              }

              In the query above, userId is a variable. The variable and its type are declared in the operation signature, signified by a $. The type of variable is a non-nullable ID. A variable's type must match the type of any argument it's used for.

              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              argument

              A key-value pair associated with a particular schema field that lets operations pass data to that field's resolver.

              Argument values can be hardcoded as literal values (shown below for clarity) or provided via GraphQL variables (recommended).

              query GetHuman {
              human(id: "200") {
              name
              height(unit: "meters")
              }
              }
              variable

              A placeholder for dynamic values in an operation allowing parameterization and reusability in requests. Variables can be used to fill arguments or passed to directives.

              query GetUser($userId: ID!) {
              user(id: $userId) {
              firstName
              }
              }

              In the query above, userId is a variable. The variable and its type are declared in the operation signature, signified by a $. The type of variable is a non-nullable ID. A variable's type must match the type of any argument it's used for.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              Apollo Client

              An open-source library for client-side state management and GraphQL operation handling in Javascript/Typescript. Apollo Client is a fully featured caching GraphQL client with integrations for React, Angular, and more.

              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              operation

              A single query, mutation, or subscription that clients send to a GraphQL server to request or manipulate data.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              mutation

              A GraphQL operation that modifies data on the server. It allows clients to perform create, update, or delete operations, altering the underlying data.

              NEW COURSE ALERT

              Introducing Apollo Connectors

              Connectors are the new and easy way to get started with GraphQL, using existing REST APIs.

              Say goodbye to GraphQL servers and resolvers—now, everything happens in the schema!

              Take the course