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

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

Fetch Product by ID

We will now create a GraphQL query to fetch data from the Fauna Database. We'll be using the productByInput input type we created earlier.

Inside grafbase/grafbase.config.ts add the following product query:

g.query('product', {
  args: { by: g.inputRef(productByInput) },
  resolver: 'products/single',
  returns: g.ref(product).optional()
})

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

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

const client = new Client()

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

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

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

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

    return null
  }
}

Because by contains optional fields, we need to check if at least one was provided in the query. If no field was provided, we can throw a GraphQLError that will be returned to the client:

import { GraphQLError } from 'graphql'

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

  if (Object.entries(by).length === 0) {
    throw new GraphQLError('You must provide at least one field to fetch by.')
  }

  // ...
}

You're probably wondering why we don't just make id a required field. You could do that but it wouldn't allow us to add other fields we want to fetch "by" easily, such as a unique field.

💡
GraphQL has a proposal for @oneOf input types which we could use here to reduce the boilerplate once it becomes officially part of the specification.

Now open Pathfinder at http://127.0.0.1:4000 and execute a GraphQL query to fetch an existing product by ID:

query {
  product(by: {
    id: "372397709974307023"
  }) {
    id
    name
    price
  }
}

You should see something like this in the response:

{
  "data": {
    "product": {
      "id": "372397709974307023",
      "name": "shoes",
      "price": 100
    }
  }
}

That's it! We can now create, update, delete and fetch products by ID. In the next step, we'll create a query to list all products.

Continue to Part 8 👉