Skip to content

sds-smith/assemble_the_jams_3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Assemble the Jams 3.2

A Playlist Generator Progressive Web App leveraging the Spotify API.

This project serves as a personal playground where I can try out new things as I continue to explore and learn new technologies and skills. It has evolved through numerous iterations since its original development in February, 2022 and holds a special place in my heart as the Codecademy project from which it grew was my first exposure to React, OAuth2.0, and fetch requests.

The main branch is up to date with branch v3.2_graphql.

Primary Tech Stack

  • Express 4.18.2
  • React.js 18.2.8
  • GraphQL 16.8.1
  • Apollo Server 4.9.5
  • Apollo Client 3.8.7

Additional Technologies used:

  • TypeScript for client-side code
  • @types/spotify-api
  • Styled Components
  • Cookie-sessions
  • Passport
  • Passport-spotify

Use Case

Spotify provides a robust search and recommendations feature which can be experienced on their own website, or on their desktop or mobile apps. When a user executes a search on Spotify, they are provided with matches in seven categories: All, Artists, Playlists, Albums, Songs, Podcasts & Shows, and Profiles. Each of these categories is itself a deep rabbit-hole, some containing even more sub-categories. An absolute wealth of information. But what if a user prefers not to sort through all of this? What if they'd like to just be served up a freshly curated playlist of tracks by many different artists, all based on a search term (artist, album, or song) of their choosing? Enter Assemble the Jams.

TRY IT OUT

A demo video of the app can be viewed by clicking on the below thumbnail.

video link

Overview of Functional Flow

On first render, a useEffect hook in AuthContext.Provider (at the top of the component tree, wrapping the App component) sends a request to the backend which authenticates the Client with Spotify.

At the same time, a useEffect in the App component looks for an authenticated user. If no user is found, audioPlayer() (exposed by a custom useAudio hook) is invoked, triggering a useEffect in useAudio to create a new Audio() object on the window and store its reference in a useRef hook.

Once the Client is authenticated, an un-authenticated user can execute keyword searches and preview select tracks using in-track controls.

Two lists are populated in the UI on execution of a keyword search:

  • 'Search Results' - the direct result of the keyword search (which may optionally include a filter to match the search term to artist, track or album)
  • 'Playlist' - a custom curated suggested playlist generated by leveraging the results of the keyword search against the Spotify 'Recommendations' algorithm.

Some, but not all, track objects returned from Spotify have a property preview, whose value is a url that can be passed into the audioRef. Otherwise, no preview is available to the un-authenticated user for that track.

At any point, the user may use the 'LOGIN' button to authenticate with their Spotify Premium account. Once the user is authenticated, the useEffect in App invokes spotifyPlayer(), triggering useAudio to load a new SpotifyPlayer() on the window using the Spotify sdk and storing its reference in spotifyRef. All audio functionality will now be passed to spotifyRef, and the user is able to hear a preview of any track regardless of whether it has a preview url.

The authenticated user is also able to modify their Premium account in two ways:

  • Save a playlist to their account (after optionally naming it and adding/deleting tracks)
  • Add/delete a track to/from their list of 'Liked Songs'

The app uses three protocols for engaging with Spotify:

  • Spotify Web Playback SDK for playing track previews with an authenticated user
  • Express Auth Router
    • Auth requests are sent to the Express server at /auth, where Client credentials are obtained via fetch request to Spotify and user credentials are obtained via Passport Spotify strategy.
  • GraphQL API
    • Search, Save, and Like requests are sent via Apollo Client queries and mutations to the Express server at /graphql where the Apollo Server middleware invokes the appropriate resolver.
    • The api layer is made up of a graphql resolvers layer and a models layer. In the previous version (v3.1), the same models layer is used, but is invoked by a controller layer corresponding to REST API endpoints. This reuse of the models layer to engage with the Spotify API demonstrates the power and flexibility of this versionable approach.

On the Client side, graphql queries and mutations are implemented in usePlaylist and useLike custom hooks which leverage useLazyQuery and useMutation hooks imported from Apollo Client.

Spotify Approval

In order to retrieve data from the Spotify API, this and all apps must be registered on the Spotify Developer portal. At that time, the app receives its own unique Client credentials and is registered in Development Mode.

In Development Mode, up to 25 Spotify users can install and use the app, but they must be explicitly added on the Developer portal before they can authenticate and actually use the app.

Assemble the Jams has been approved by Spotify as a full production app is no longer in Development Mode.

To attain this approval, this app underwent a rigorous review process by Spotify to ensure that it complied with all requirements in the Spotify Developer Policy and Spotify Design Guidelines. As a full production app, Assemble the Jams has been granted access to an increased API request quota and an unlimited number of Spotify users can install and use it without being explicitly added to a list of users in Developer portal.

DefinitelyTyped - TypeScript node package for Spotify API

The node package @types/spotify-api is a package containing type definitions for the Spotify Web API, including complex types for data objects, requests, and responses relating to the Spotify API.

I've had the opportunity to contribute three small pieces of code to this open-source package:

  • RecommendationsObject - I was able to submit an update to this type after discovering that it contained an incorrectly-typed Track object (TrackObjectSimplified, which does not contain and album property). But while TrackObjectFull (previously the only available alternative) does contain an album property, that album Object yields album_type in all lower-case. This exposes a small bug in the Spotify API, as the all-caps album_type in the recommendations response Track is inconsistent with all other endpoint responses.
  • RecommendationTrackObject - This is a new Track Object type added to the package, specific to the recommendations response returned from a recommendations with seeds request. This track object is identical to the TrackObjectFull except that it contains a newly-created RecommendationAlbumObject.
  • RecommendationAlbumObject - Similarly, this extends the AlbumObjectSimplified, but yields album_type in all caps instead of lowercase.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published