https://github.com/ricin9/chinook-graphql
GraphQL API for the Chinook sample database
https://github.com/ricin9/chinook-graphql
chinook-database graphql yoga-graphql
Last synced: 6 months ago
JSON representation
GraphQL API for the Chinook sample database
- Host: GitHub
- URL: https://github.com/ricin9/chinook-graphql
- Owner: ricin9
- Created: 2024-10-19T19:02:41.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2024-10-25T20:55:00.000Z (12 months ago)
- Last Synced: 2025-02-13T10:34:37.655Z (8 months ago)
- Topics: chinook-database, graphql, yoga-graphql
- Language: TypeScript
- Homepage: https://chinook-graphql.miloudi.dev
- Size: 90.8 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Chinook GraphQL API
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.
## Features
- GraphQL API for accessing [Chinook Database](https://www.kaggle.com/datasets/ranasabrii/chinook) 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## Getting Started
### Prerequisites
- Node.js
- Pnpm
- Cloudflare account with Workers and D1 access### Installation
Clone the repository:
```bash
git clone https://github.com/ricin9/chinook-graphql.git
cd chinook-graphql
```Install dependencies:
```bash
pnpm install
```## Technologies
- 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## Project Structure
```
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
```## Environment Setup
### Set up Cloudflare D1 database:
- Create a D1 instance on your Cloudflare dashboard, or using the `wrangler` CLI
```bash
pnpm wrangler d1 create
```- Link the newly created D1 instance to this project by adding the binding in wrangler.toml:
```toml
[[d1_databases]]
binding = "DB" # Name used in the Worker
database_name = "" # Name of your D1 database
database_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](https://github.com/lerocha/chinook-database/blob/master/ChinookDatabase/DataSources/Chinook_Sqlite_AutoIncrementPKs.sql)
- Upload the sample database to the newly created D1 instance
```bash
pnpm wrangler d1 execute database_name < Chinook_Sqlite_AutoIncrementPKs.sql
```## Usage
Running the Worker Locally
To test the API locally with Wrangler:
```bash
pnpm wrangler dev
```### Testing Queries
Once the server is running, you can access the GraphQL playground at the local URL displayed by Wrangler, and start querying the database.
#### Example Queries
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:
```graphql
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
```graphql
{
customer(id: 4) {
customerId
firstName
lastName
company
phone
supportRep {
employeeId
firstName
lastName
phone
}
invoices(first: 5) {
invoiceId
invoiceDate
total
}
}
}
```## Performance
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## Deployment
To deploy the project to Cloudflare Workers:
```bash
pnpm wrangler deploy
```