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

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

Fetch Product by ID or Unique field query

GraphQL queries are typically used to fetch data and return it in a certain shape. We will create two queries in parts 7 and 8:

  • product — fetch a single product by the id or slug value

  • products — fetch all products in the database and return them as a list

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

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

import { connect } from '@planetscale/database'
import { GraphQLError } from 'graphql'
import { config, options } from '../../lib'

const conn = connect(config)

export default async function ProductsSingle(_, { by }) {
  // ...
}

Just like before we add the necessary imports and ProductsSingle default export.

Now we'll add a bit more to the file that will:

  • Throw an error if both id and slug are passed

  • Select the product from the database WHERE the id is of the value passed

  • Select the product from the database WHERE the slug is of the value passed

  • Throw an error if no id or slug values are passed

The full delete.ts should look something like this:

import { connect } from '@planetscale/database'
import { GraphQLError } from 'graphql'
import { config, options } from '../../lib'

const conn = connect(config)

export default async function ProductsSingle(_, { by }) {
  let results

  try {
    if (by.id !== undefined && by.slug !== undefined) {
      throw new GraphQLError('Only one of ID or Slug should be provided')
    } else if (by.id !== undefined) {
      results = await conn.execute(
        'SELECT * FROM products WHERE id = ? LIMIT 1',
        [by.id],
        options
      )
    } else if (by.slug !== undefined) {
      results = await conn.execute(
        'SELECT * FROM products WHERE slug = ? LIMIT 1',
        [by.slug],
        options
      )
    } else {
      throw new GraphQLError('ID or Slug must be provided')
    }

    return results?.rows[0] ?? null
  } catch (error) {
    console.log(error)

    return null
  }
}

Open Pathfinder and execute the following GraphQL query to fetch by id:

{
  product(by: { id: "1" }) {
    id
    name
    slug
    onSale
    price
  }
}

You can also fetch it by slug if you update the query to use that argument instead:

{
  product(by: { slug: "shoes" }) {
    id
    name
    slug
    onSale
    price
  }
}

👉 Continue to Part 8