15. Mutations
2m

Code-Along: Add a mutation for incrementing the number of views for a track

  1. Open up schema.graphql.

  2. Add the Mutation type. We'll define the incrementTrackViews field here. It will return a TrackMutationResponse. It also uses a trackId argument to specify which track is getting more views.

    type Mutation {
    "Increase the number of page views for a track by 1"
    incrementTrackViews(trackId: ID!): TrackMutationResponse!
    }
  3. Define the TrackMutationResponse using the fields we went over earlier. We'll also return a track field to represent the track we mutated.

    type TrackMutationResponse {
    "The HTTP code for the mutation"
    code: Int!
    "A flag for whether or not the mutation completed successfully"
    success: Boolean!
    "Human-readable message with additional info about the mutation"
    message: String!
    "The mutated Track object"
    track: Track
    }

Check your work

  1. Open up Sandbox and add a new tab.

  2. Build a mutation:

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

    Variables:

    {"incrementTrackViewsId": "c_0"}
  3. When we run the operation, we should get an error "Cannot return null for non-nullable field Mutation.".

What does this error mean? What does it tell us we need to do?

Adding the data source

  1. What REST API endpoint do we need for the data we want?

    PATCH /track/:id/numberOfViews
  2. Open up datasources/catstronauts-api.js and add a new method to increment the number of track views using the REST API endpoint above.

    incrementTrackViews(id) {
    return this.patch(`track/${id}/numberOfViews`)
    }

Adding a resolver

  1. Open up resolvers.js.

  2. Let's add a Mutation key to our resolvers object and add our incrementTrackViews resolver function.

    Mutation: {
    incrementTrackViews: () => {
    },
    },
  3. Inside, we need to call the incrementTrackViews method we just set up. For that, we need two things: the track's id, and the data source. We can get the track's id through the arguments parameter, and the data source through the context parameter, so we'll destructure those.

    Mutation: {
    incrementTrackViews: (_, { trackId }, { dataSources }) => {
    return dataSources.catstronautsAPI.incrementTrackViews(trackId);
    },
    },
  4. But according to our schema, we don't just return the track, we want to return more information. See TrackMutationResponse type in the schema.

    So we'll await the results of this API call, before returning that other information (code, success, message).

    incrementTrackViews: async (_, {trackId}, {dataSources}) => {
    const track = await dataSources.catstronautsAPI.incrementTrackViews(
    trackId
    );
    return {
    code: 200,
    message: 'Successfully incremented track views',
    success: true,
    track
    };
    },

Check your work round 2

Test our query in Apollo Studio again... and it works!

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

Variables:

{"incrementTrackViewsId": "c_0"}
Previous
Next