Backend
Now we're ready to write the last one of the cart item's CRUD operations, decreaseCartItem
. Not surprisingly, it does have a similar signature and implementation as increaseCartItem
. Still it does have some interesting peculiarities that we'll cover in this section, specially to make sure users can mindlessly hit the minus button as much as they want.
First thing we'll do is adding a field called decreaseCartItem
to the schema's Mutation
type.
This operation receives an input of type DecreaseCartItemInput
, which we'll define momentarily, and it returns a Cart
type.
Create an input
type called DecreaseCartItemInput
, with an id
and cartId
fields.
This is what these two additions look like in our schema:
type Mutation {
# ...
decreaseCartItem(input: DecreaseCartItemInput!): Cart
}
# ...
input DecreaseCartItemInput {
id: ID!
cartId: ID!
}
Remember to generate the types associated with these new changes with npm run codegen
before moving on to defining the new mutation's resolver, otherwise you'll run into type errors.
The bulk of the decreaseCartItem
resolver will be handled by prisma.cartItem.update
's data.quantity.decrement
, which atomically decrements the cart item's quantity.
Fun fact: we could get tricky and instead of passing decrement: 1
to
update
, use increment: -1
. But let's take the boring path and choose clear
over clever.
Besides decrementing by 1, we need to prevent users from setting negative quantities. To do that we'll check if quantity is negative after decrementing, and remove the item if we go below 0
. We can do that using something like this:
if (quantity <= 0) {
await prisma.cartItem.delete({
where: {
id_cartId: {
id: input.id,
cartId: input.cartId,
},
},
});
}
Finally, the resolver should return the corresponding cart.
Here's what the resolver should look like:
const resolvers: Resolvers = {
// ...
Mutation: {
// ...
decreaseCartItem: async (_, { input }, { prisma }) => {
const { cartId, quantity } = await prisma.cartItem.update({
data: {
quantity: {
decrement: 1,
},
},
where: { id_cartId: { id: input.id, cartId: input.cartId } },
select: {
quantity: true,
cartId: true,
},
});
if (quantity <= 0) {
await prisma.cartItem.delete({
where: {
id_cartId: {
id: input.id,
cartId: input.cartId,
},
},
});
}
return findOrCreateCart(prisma, cartId);
},
},
};
We can now decrease cart item's by going to http://localhost:3000/api and fire up the mutation from GraphiQL. Feel free to press CMD + Enter many times, like a madperson, just to verify the quantity never goes below zero, which would be too abstract anyway.
mutation decreaseCartItem {
decreaseCartItem(input: { id: "1", cartId: "oneweekgraphql" }) {
id
items {
name
quantity
unitTotal {
formatted
amount
}
lineTotal {
formatted
amount
}
}
subTotal {
formatted
}
}
}
If things went right, you should see a JSON response similar to this:
{
"data": {
"decreaseCartItem": {
"id": "oneweekgraphql",
"items": [
{
"name": "Shirt",
"quantity": 1,
"unitTotal": {
"formatted": "$10.00",
"amount": 1000
},
"lineTotal": {
"formatted": "$10.00",
"amount": 1000
}
}
],
"subTotal": {
"formatted": "$10.00"
}
}
}
}