Build and Deploy a GraphQL API to the Edge with Fauna — Part 5

Build and Deploy a GraphQL API to the Edge with Fauna — Part 5

Update Product Mutation

Let's now move on to creating a GraphQL mutation to update products by ID.

Let's begin by updating the Grafbase Configuration to add a mutation that accepts the following arguments:

  • by — something we can use to pass id to target the product we want to update

  • input — the actual input of the fields we want to update. These fields should be optional.

Inside grafbase/grafbase.config.ts you will want to add the following:

const productUpdateInput = g.input('ProductUpdateInput', {
  name: g.string().optional(),
  price: g.int().optional(),
})

const productByInput = g.input('ProductByInput', {
  id: g.id().optional(),
})

g.mutation('productUpdate', {
  args: {
    by: g.inputRef(productByInput),
    input: g.inputRef(productUpdateInput)
  },
  resolver: 'products/update',
  returns: g.ref(product).optional()
})

Next, create the file grafbase/resolvers/products/update.ts and add the following:

import { Client, fql, FaunaError } from 'fauna'

const client = new Client()

export default async function ProductsUpdate(_, { by, input }) {
  const { id } = by

  try {
    const documentQuery = fql`
      products.byId(${id}).update(${input}) {
        id,
        name,
        price
      }
    `

    const { data } = await client.query(documentQuery)

    return data
  } catch (error) {
    if (error instanceof FaunaError) {
      console.log(error)
    }

    return null
  }
}
💡
FQL is amazing! We can update by ID and return the data in the same request... It feels very much like GraphQL! 🤩

Let's finish by adding some additional validation to the resolver. We want to check at least one by and input field is present. Let's update the ProductsUpdate resolver to include the following:

import { GraphQLError } from 'graphql'

export default async function ProductsUpdate(_, { by, input }) {
  const { id } = by

  if (Object.entries(input).length === 0) {
    throw new GraphQLError('At least one field to update must be provided.')
  }

  // ...
}

You can now execute the GraphQL mutation updateProduct and pass it on of the id values that were returned from the previous createProduct mutations.

Open Pathfinder at http://127.0.0.1:4000 and execute the following:

mutation {
  productUpdate(by: {
    id: "372390645805875406"
  }, input: {
    name: "New shoes"
  }) {
    id
    name
    price
  }
}

You should get a response that looks something like this:

{
  "data": {
    "productUpdate": {
      "id": "372390645805875406",
      "name": "New shoes",
      "price": 1000
    }
  }
}

We can also check that the validation on at least one input value being present by executing the following mutation:

mutation {
  productUpdate(by: {
    id: "372390645805875406"
  }, input: {

  }) {
    id
    name
    price
  }
}

If everything "works" as expected, you should see the following error:

{
  "data": null,
  "errors": [
    {
      "message": "At least one field to update must be provided.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "productUpdate"
      ]
    }
  ]
}

That's it! We can now create and update products using GraphQL mutations.

Continue to Part 6 👉