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 (available in preview) series. Remote Joins in Hasura allows you to join data across tables and remote data sources. You can sign up here if you'd like to be notified when we launch. Head to the PR to check out more details, read the preview docs, and to try out a test Hasura image that you can spin up. Jump on our discord or comment on github and let us know what you think!

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 everytime 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/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.


Hasura is an open-source engine that gives you realtime GraphQL APIs on new or existing Postgres databases, with built-in support for stitching custom GraphQL APIs and triggering webhooks on database changes.


PS: Weโ€™re hiring!