This repository hosts a GraphQL API built using Yoga and the Cloudflare D1 database, designed to run on Cloudflare Workers. The API is based on the Chinook Database, a sample dataset commonly used for learning SQL.
- GraphQL API for accessing Chinook Database data
- Built with Yoga GraphQL for flexible and efficient GraphQL functionality
- Runs on Cloudflare Workers for serverless deployment
- Uses Cloudflare D1 as the database solution
- Node.js
- Pnpm
- Cloudflare account with Workers and D1 access
Clone the repository:
git clone https://github.com/ricin9/chinook-graphql.git
cd chinook-graphql
Install dependencies:
pnpm install
- GraphQL Yoga - For creating a fast and flexible GraphQL API
- Cloudflare D1 - Managed SQL database based on SQLite
- Cloudflare Workers - Serverless environment for deploying web services
- Chinook Database - Sample data representing a digital media store, containing tables for artists, albums, media tracks, and more
- Drizzle ORM - has nice a relational api with type safety
chinook-graphql/
├── drizzle/ # contains chinook database's schema in sql (commented for now)
├── src/
│ ├── db/ # Contains drizzle schema, and a database instance getter
│ ├── resolvers/ # Implementation of GraphQL resolvers defined in gql-typedefs.ts
│ ├── dataloaders.ts # Implementation of all dataloaders used by the resolvers
│ ├── gql-typedefs.ts # GraphQL SDL
│ ├── gql-schema.ts # GraphQL Schema (resolvers)
│ └── server.ts # Entry point for the Cloudflare Worker
│ └── .... # other files
├── wrangler.toml # Cloudflare Wrangler configuration
└── package.json
- Create a D1 instance on your Cloudflare dashboard, or using the
wrangler
CLI
pnpm wrangler d1 create <database_name>
- Link the newly created D1 instance to this project by adding the binding in wrangler.toml:
[[d1_databases]]
binding = "DB" # Name used in the Worker
database_name = "<YOUR_D1_DB_NAME>" # Name of your D1 database
database_id = "<YOUR_D1_DB_ID>"
migrations_dir = "drizzle/migrations" # not really needed now since we're going to upload the chinook dump directly
-
Download the Chinook sample database from this link
-
Upload the sample database to the newly created D1 instance
pnpm wrangler d1 execute database_name < Chinook_Sqlite_AutoIncrementPKs.sql
Running the Worker Locally
To test the API locally with Wrangler:
pnpm wrangler dev
Once the server is running, you can access the GraphQL playground at the local URL displayed by Wrangler, and start querying the database.
Here are some sample queries to get you started:
- List the first 20 artists, each with their first 10 albums, each album with its first 15 tracks, each track with its genre:
query {
artists(limit: 20) {
artistId
name
albums(first: 10) {
albumId
title
tracks(first: 15) {
trackId
name
genre {
name
}
bytes
composer
}
}
}
}
- Fetch customer with id=4 along with their support rep (an employee) and with their first 5 invoices
{
customer(id: 4) {
customerId
firstName
lastName
company
email
phone
supportRep {
employeeId
firstName
lastName
email
phone
}
invoices(first: 5) {
invoiceId
invoiceDate
total
}
}
}
All resolvers use conditional joins and/or dataloaders to hit the database the minimum time possible
- The 1st example query above hits the databses 3 times only while having 4 levels of nesting and eager loading of one-to-many relation (albums, and albums->tracks)
- Without dataloders or joins this would hit the database up to 1 + 20 + 20 _ 10 + 20 _ 15 * 10 = 3221 times
- The 2nd example hits the database 2 times with 2 levels of nesting while fetching a one to many relation (invoices)
- Without dataloders or joins this would hit the database up to 1 + 1 + 5 = 7 times
To deploy the project to Cloudflare Workers:
pnpm wrangler deploy