Building a Music Playlist App with Gatsby, Contentful and Hasura Remote Joins
TL;DR
Join music data in your database with audio source files in Contentful with GraphQL and Hasura Remote Joins. Handle authentication using Auth0.
Instant setup. App Source Code -> gatsby-contentful-auth0
In this example, we will look at how a music playlist app can be built with Gatsby and CMS as Contentful. Contentful is an API First CMS to build digital products. It offers a GraphQL API which can be joined with Hasura using Remote Schema. We will learn how these multiple data sources can be merged with existing data in Hasura. In the music playlist app, we store metadata about music tracks, albums, playlist and users in Postgres database and query it using Hasura GraphQL. We will use Contentful to store and retrieve audio tracks required to play music on the app. For user authentication we will make use of Auth0.
Here's a simple schema representation of the music playlist app that we are going to build. There's an album
table which can have multiple tracks. Similarly there's a playlist
table which can have multiple tracks. A playlist is linked to a user via the user
table.
The track information is stored in Postgres but we use Contentful to store and manage actual audio tracks.
Getting Started
This post is a part of our Remote Joins series. Remote Joins in Hasura allows you to join data across tables and remote data sources.
- Deploy GraphQL Engine on Hasura Cloud and setup PostgreSQL via Heroku:
Get the Hasura app URL (say whatsapp-clone.hasura.app
)
Now let's setup Auth0 for the Authentication part. Refer to the Auth0 integration guide for the configuration.
In the sample app that you cloned above, you need to apply the rule which syncs user signups to the postgres database. So every time a user signs up on the app, the user data is inserted into the database.
Storing Media Files in Contentful
Let's create necessary content types in Contentful. Under Content model, create a new content type for Tracks and add the following fields -> id
and track
. We will use the id
field to connect this data with Hasura track table. Note that track field is of Media type and we will make use of it to create audio source files.
Adding Contentful as Remote Schema
To be able to query Contentful data via Hasura, it needs to be added as a Remote Schema using the Hasura Console.
- Get the GraphQL Content API Endpoint in the following format:
https://graphql.contentful.com/blog/content/v1/spaces/<space-id>
And replace with the appropriate space id.
- In Contentful dashboard, click on Settings. Under Space Settings click on API keys. Copy the Space ID and paste in the above endpoint.
- Now copy Content Delivery API - access token and use it in Authorization headers like below:
Authorization: Bearer <access_token>
- In Hasura Console, head to
Remote Schemas
and enter GraphQL Server URL with the above contentful endpoint. Under Additional Headers, enter the Authorization header with the access_token as mentioned above.
Create Remote Relationship from playlist_track
table to tracksCollection
type of Contentful.
Under configuration for tracksCollection, we declare a where clause to say:
id: From Column -> track_id
This ensures that while querying for tracks, we get only the relevant audio source files.
Now the GraphQL query to fetch this data in a single API call would look like the following:
query PlaylistQuery {
playlist {
name
tracks {
track_details {
name
}
track {
items {
track {
url
}
}
}
}
}
}
Note that the nested query track
comes from Contentful and it will apply the filter of track.id = playlist_track.track_id, there by giving only the relevant audio track information.
Authorization
We have merged two different data sources and retrieved data in a single GraphQL query. With role based permissions, we can take care of the permissions required for the app. For example, a user should be able to add tracks only to the playlist that they created.
Insert some sample data to see how the response structure looks like for the above GraphQL query.
The track URL information comes from Contentful and more metadata can be fetched about that track. Using the URL, we build the playlist app showing the tracks belonging to the user's playlist.