5. Resolving a mutation successfully
3m

🧪 Mutation resolvers

We've set up our data source to make a PATCH call to our REST API. Now it's time to write resolvers to put our data source to work.

In the server/src folder, let's open up the resolvers.js file. We need to add another entry to our resolvers object for our mutation.

We can add it just below our Query resolvers, and we need to give it the same name as in our schema, which is Mutation (note the capital M!).

const resolvers = {
Query: {
// … query resolvers
},
Mutation: {
// where our new resolver function will go
}
};

Inside this Mutation object, we'll add the resolver function for our mutation, which also needs to have the same name as in our schema incrementTrackViews. And of course, let's add a helpful comment at the top.

// increments a track's numberOfViews property
incrementTrackViews: (parent, args, context, info) => {},

Which of these are true about the structure of the resolvers object?

We won't need the parent argument in this resolver, because it's for a root field in our schema. By convention, we'll just add an underscore. We do need to destructure the second parameter args to retrieve the id of the track we're updating. As usual, we'll also destructure the third parameter context for the dataSources object. And finally, we have no need for the fourth parameter info.

Update the resolver function in resolvers.js:

incrementTrackViews: (_, {id}, {dataSources}) => {
// where we'll call the TrackAPI
},

In the body of the resolver, we want to call the method we added to our TrackAPI. As we saw in Lift-off II, we get access to that TrackAPI through the dataSources object by configuring it in the Apollo Server options.

So inside the incrementTrackViews resolver body, we'll call dataSources.trackAPI.incrementTrackViews, passing it the id from args.

dataSources.trackAPI.incrementTrackViews(id);

So far, we've always immediately returned the results of our TrackAPI calls, because the results match the structure required by our schema.

However, in this case, we have 3 fields required by our schema that are not present in the returned response: code, success and message. This makes sense because they are tied to the REST operation status itself, so we need to set those 3 based on that status.

Why can't this resolver immediately return the results of the TrackAPI call in this case?

📄 Fulfilling the schema requirements

First, let's wait for the TrackAPI call to finish returning the data. We can do this by making the function async, then storing the results in a variable called track, making sure to await the results.

incrementTrackViews: async (_, {id}, {dataSources}) => {
const track = await dataSources.trackAPI.incrementTrackViews(id);
},

Next, let's return an object with all the properties needed to fulfill our schema. For now, we'll assume that the API call was successful, and worry about the error handling in the next lesson.

return {
code: 200,
success: true,
message: `Successfully incremented number of views for track ${id}`,
track
};

So here the code will return 200, the success property will be set to true, and we can return message to show that the number of views was successfully incremented for this specific track ID. And finally, we can return the modified object, track.

In the end, the resolvers object should have a new entry that looks like this:

Mutation: {
// increments a track's numberOfViews property
incrementTrackViews: async (_, { id }, { dataSources }) => {
const track = await dataSources.trackAPI.incrementTrackViews(id);
return {
code: 200,
success: true,
message: `Successfully incremented number of views for track ${id}`,
track,
};
},
},

Code Challenge!

Add a resolver for the new assignSpaceship mutation provided in the schema. Use the datasources.spaceAPI class and its method assignSpaceshipToMission, which takes the spaceshipId and the missionId as arguments (in that order). This method returns an object with the newly updated spaceship and mission. Follow the schema requirements to return an object for the successful result. code should be 200, success should be true and message should say Successfully assigned spaceship ${spaceshipId} to mission ${missionId}

All right, we've got our successful case resolved, but what happens when our TrackAPI throws an error? Let's take care of this in the next lesson.

Previous
Next