{"id":23674517,"url":"https://github.com/apollographql/spotify-showcase","last_synced_at":"2026-05-28T01:07:47.253Z","repository":{"id":130543359,"uuid":"580533484","full_name":"apollographql/spotify-showcase","owner":"apollographql","description":"A Spotify clone that showcases the Apollo GraphQL platform.","archived":false,"fork":false,"pushed_at":"2025-08-28T23:53:28.000Z","size":8352,"stargazers_count":142,"open_issues_count":34,"forks_count":19,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-08-29T04:29:08.690Z","etag":null,"topics":["apollo-client","apollo-graphql","apollo-server","graphql"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apollographql.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-12-20T19:57:09.000Z","updated_at":"2025-08-26T20:17:48.000Z","dependencies_parsed_at":"2023-10-19T13:26:33.811Z","dependency_job_id":"2248e057-3d5c-4044-9025-c25aed7d75a2","html_url":"https://github.com/apollographql/spotify-showcase","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/apollographql/spotify-showcase","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Fspotify-showcase","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Fspotify-showcase/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Fspotify-showcase/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Fspotify-showcase/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apollographql","download_url":"https://codeload.github.com/apollographql/spotify-showcase/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apollographql%2Fspotify-showcase/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273224889,"owners_count":25067184,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apollo-client","apollo-graphql","apollo-server","graphql"],"created_at":"2024-12-29T13:07:06.042Z","updated_at":"2026-05-28T01:07:42.218Z","avatar_url":"https://github.com/apollographql.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://www.apollographql.com/\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/apollographql/apollo-client-devtools/main/assets/apollo-wordmark.svg\" height=\"100\" alt=\"Apollo Client\"\u003e\u003c/a\u003e\n\u003c/div\u003e\n\n# React + Apollo Spotify Showcase\n\n\u003cimg width=\"1512\" alt=\"Screenshot 2023-03-07 at 5 13 26 PM\" src=\"https://user-images.githubusercontent.com/565661/223585591-93b5b6d2-d3d8-44fb-9b30-8bb5fc508f90.png\"\u003e\n\n## Architecture\n\nThe overall API architecture is made up of two GraphQL servers, one exposing subscription/mutation functionality and the other exposing query functionality. Both GraphQL servers use the Spotify REST API as their datasource, but we are hosting the subscription server on dedicated infrastructure (Railway) and the other on serverless functions (Netlify).\n\nThe Apollo Router routes incoming traffic from the client application and integrates with GraphOS to receive schema updates and report usage metrics.\n\n```mermaid\ngraph LR;\n\nsubgraph \"Netlify\"\n  web[\"Website\\n(client app)\"]\nend\n\nsubgraph \"Railway\"\n  router{\"Apollo Router\"}\n  playbackSubgraph[\"Playback Subgraph\\n(subriptions/mutations)\"]\n  spotifySubgraph[\"Spotify Subgraph\\n(queries)\"]\nend\n\nsubgraph \"Apollo\"\n  schema[\"Schema Pipeline\"]\n  usage[\"Usage Reporting\"]\nend\n\nsubgraph \"Spotify\"\n  spotifyREST[Spotify REST API]\nend\n\nweb \u003c--\u003e router\nrouter \u003c--\u003e|Schema Updates\\nUsage Reporting| Apollo\nrouter \u003c--\u003e spotifySubgraph\nrouter \u003c--\u003e playbackSubgraph\nplaybackSubgraph \u003c--\u003e spotifyREST\nspotifySubgraph \u003c--\u003e spotifyREST\n\nclassDef spotifyBox color:#FFFFFF,fill:#1DB954,stroke:#FFFFFF,stroke-width:2px;\nclassDef netlifyBox color:#014847,fill:#FFFFFF,stroke:#32e6e2,stroke-width:2px;\nclassDef railwayBox color:#000000,fill:#FFFFFF,stroke:#000000,stroke-width:2px;\nclassDef apolloBox color:#3f20ba,fill:#FFFFFF,stroke:#3f20ba,stroke-width:2px;\n\nclass Spotify spotifyBox\nclass Netlify netlifyBox\nclass Netlify-Function netlifyBox\nclass Railway railwayBox\nclass Apollo apolloBox\n```\n\n**\\*Note**: We are using only the Spotify REST API as our datasource for demonstration purposes. The subscriptions subgraph implements a polling mechanism that we host on a dedicated infrastructure while the \"query\" subgraph is hosted on serverless infrastructure\\*\n\n## Getting started\n\nWhat do you want to do next with this demo app?\n\n### I want to play around with the public version of the demo\n\n1. Visit the [public Apollo Explorer instance](https://studio.apollographql.com/public/spotify-ev3of9/variant/prod/home) to interact with the graph (No GraphOS account required)\n\n- [Query the graph](https://studio.apollographql.com/public/spotify-ev3of9/variant/prod/explorer) _(**Spotify account required**) - OAuth workflow with be initiated from Apollo Explorer to login to our Spotify account to run any operation_\n  - Try having your Spotify app playing on your phone or desktop and then run [this mutation](https://studio.apollographql.com/public/spotify-ev3of9/variant/prod/explorer?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4RxighigSwiQAIAFXGAZwTIBtcBPAI1ygGsBZHfI04ADqkSIgA6Ua9Jqw4lBwkWIYs27AMp4UCOUMV6SBKlMYEkAc136AvpZE3hVkFaA)\n- [View the graph's schema](https://studio.apollographql.com/public/spotify-ev3of9/variant/prod/schema/reference)\n\n### I want to re-create this demo in my GraphOS account\n\n\u003e **Note**: To create graphs, you must have the [Org Administrator or Graph Administrator](https://www.apollographql.com/docs/graphos/org/members#organization-wide-member-roles) role for your GraphOS organization.\n\n1. Clone this repo.\n2. Create a [personal API key](https://www.apollographql.com/docs/graphos/org/account/#personal-api-keys).\n3. Run the script below using your personal API key.\n\n   ```sh\n   AUTH={YOUR_API_KEY} npm run graphos-demo\n   ```\n\n   If you have multiple organizations, the script will prompt you to select which organization the graph should be in.\n\n### I want to run the client app locally\n\n1. Clone this repo.\n2. From the root of the folder, install the dependencies.\n\n   ```sh\n   npm install\n   ```\n\n3. From the root of the folder, start the client app.\n\n   ```sh\n   npm start\n   ```\n\n4. Visit the website at http://localhost:3000.\n\nBy default, the client app is pointing to the _locally-running_ backend URL. Follow the section below for \"I want to run the backend locally\" (you can choose to use Docker, or not).\n\nLocal subscriptions using `rover dev` is currently a work-in-progress, so features that use subscriptions are not functional (such as listening to playback state). You can change the URL the client application is pointing at by editing the `.env.development` file with `VITE_SERVER_HOST` and setting it to the production URL (uncomment the second line).\n\n### I want to run the backend locally - using Docker\n\nYou will need a GraphOS organization with an Enterprise plan or [Enterprise trial plan](https://studio.apollographql.com/signup?type=enterprise-trial) to utilize all the GraphOS features.\n\n1. Follow the steps in the \"I want to re-create this demo in my GraphOS account\" section above.\n2. Find the newly-created graph in [GraphOS Studio](https://studio.apollographql.com/). Create a [Graph API key](https://www.apollographql.com/docs/graphos/api-keys/#graph-api-keys) from the Settings page, with the default \"Graph Admin\" permissions.\n3. Create a `.env` file at the root of this repository and add in the following variables:\n\n   ```\n   APOLLO_GRAPH_REF={YOUR_DEMO_GRAPH_ID}@main\n   APOLLO_KEY={YOUR_GRAPH_API_KEY}\n   CALLBACK_URL=http://router:4000\n   ```\n\n4. Start the router and subgraphs:\n\n   ```\n   npm run docker:run\n   ```\n\n   - Supergraph - http://localhost:4000\n   - Spotify Subgraph - http://spotify:4001 (inaccessible in cluster)\n   - Playback Subgraph - http://playback:4002 (inaccessible in cluster)\n\n5. If you want to run any queries through Apollo Explorer, you'll need to disable persisted queries. You can disable this in `router/router.yaml` by commenting out the `persisted_queries` configuration.\n\n   ```yaml\n   # persisted_queries:\n   #   enabled: true\n   #   safelist:\n   #     enabled: true\n   #     require_id: false\n   ```\n\n   Re-run the `docker:run` command.\n\n### I want to run the backend locally\n\nYou will need a GraphOS organization with an Enterprise plan or [Enterprise trial plan](https://studio.apollographql.com/signup?type=enterprise-trial) to utilize all the GraphOS features.\n\n1. Follow the steps in the \"I want to re-create this demo in my GraphOS account\" section above.\n2. Find the newly-created graph in [GraphOS Studio](https://studio.apollographql.com/). Create a [Graph API key](https://www.apollographql.com/docs/graphos/api-keys/#graph-api-keys) from the Settings page, with the default \"Graph Admin\" permissions.\n\n3. Create a `.env` file at the root of this repository and add in the following variables:\n\n   ```\n   APOLLO_GRAPH_REF={YOUR_DEMO_GRAPH_ID}@main\n   APOLLO_KEY={YOUR_GRAPH_API_KEY}\n   CALLBACK_URL=http://router:4000\n   ```\n\n4. [Download](https://www.apollographql.com/docs/router/quickstart#1-download-and-extract-the-apollo-router-binary) the latest router binary to the `router` folder.\n\n5. Build and start the subgraphs. In the root of the project, run:\n\n   ```\n   npm run build\n   ```\n\n   ```\n   npm run start:spotify\n   ```\n\n   and in another terminal:\n\n   ```\n   npm run start:playback\n   ```\n\n   - Spotify Subgraph - http://localhost:4001\n   - Playback Subgraph - http://localhost:4002\n\n   \u003e **Note:** If you make any edits to the subgraph files, you'll need to re-build and restart the subgraphs manually. If you're looking to do local development, you may want to navigate to each subgraph folder and run `npm run dev` instead, which will watch for changes and restart the subgraph automatically.\n\n6. In a new terminal, start the router:\n\n   ```\n   APOLLO_KEY={YOUR_DEMO_GRAPH_ID}@main APOLLO_GRAPH_REF={YOUR_GRAPH_API_KEY} CALLBACK_URL=http://127.0.0.1:4000 npm run start:router\n   ```\n\n   - Supergraph - http://localhost:4000\n\n7. If you want to run any queries through Apollo Explorer, you'll need to disable persisted queries. You can disable this in `router/router.yaml` by commenting out the `persisted_queries` configuration.\n\n   ```yaml\n   # persisted_queries:\n   #   enabled: true\n   #   safelist:\n   #     enabled: true\n   #     require_id: false\n   ```\n\n   Restart the router to run it with the latest config changes.\n\n### Debugging the subgraphs or client locally with VS Code\n\nThere are launch configurations for the client project and subgraph projects. You can navigate to the debug tab of VS Code and launch any of the projects. They will default to the following urls:\n\n- Client App - http://localhost:3000\n- Spotify Subgraph - http://localhost:4001\n- Playback Subgraph - http://localhost:4002\n\n#### Subgraph responsibilities\n\n**playback** - This subgraph has been designed to handle the Subscription/Mutation operations for our graph. The subgraph is hosted on a dedicated piece of infrastructure (Railway) because it needs to be long lived with subscriptions support.\n\n**spotify** - This subgraph handles all of the Query operations for our graph and is hosted on serverless infrastructure (Netlify/AWS Lambda). Hosting in serverless is more cost effective for this single service in our overall architecture.\n\n## Feedback survey\n\nIf you used the React + Apollo Spotify Showcase and have two minutes then we'd\nreally appreciate it if you filled out [this survey](https://o0urpu09l9p.typeform.com/to/SrKsN0nv) -\nit really helps us improve!\n\n## Exploring the codebase?\n\nIf you're exploring the codebase and not sure where to get started, try the\nfollowing:\n\n**Client**\n\n- [`client/src/router.tsx`](./client/src/router.tsx) - This defines all routes\n  used in the app. To view the source code for a given route, follow the import\n  for the route component.\n- [`client/src/index.tsx`](./client/src/index.tsx) - This is the entry point to\n  the client app. This defines the providers used in the app.\n\n**Server**\n\n- [`server.ts`](./server.ts) - This defines the Apollo GraphQL\n  server used to serve the Spotify GraphQL schema.\n- [`server/src/resolvers/`](./server/src/resolvers/) - This defines the\n  resolvers used to resolve types and fields in the schema. The file names\n  correspond to their respective types in the schema.\n- [`server/src/dataSources/spotify.ts`](./server/src/dataSources/spotify.ts) -\n  Defines the Spotify client used to make REST calls to Spotify's REST API.\n\n## About\n\nApollo Client's newest features unlock powerful UI development capabilities when\nused with React 18. Using Suspense via `useSuspenseQuery` is one such\ncapability, as is `useBackgroundQuery`. Both of these will be shipped in 3.8.0.\nThese hooks, along with the already-available `useFragment` hook and the GraphQL\n`@defer` directive, comprise a toolkit for the UI developer to implement the\n_render-as-you-fetch_ pattern throughout the component tree.\n\n[@jerelmiller](https://github.com/jerelmiller) started building this application\nwhile building `useSuspenseQuery` in an effort to dogfood the changes with a\nnon-trivial app. Apollo Client and GraphQL are built to be both approachable and\nscalable; to-do apps are the former but not the latter. A Spotify clone - and it\nreally is a clone (👀 that CSS) - offered a much more robust proving ground for\nthe functionality we were building. As the team used it more and more, we\ndecided that if we open-sourced it then the community could use it to try things\nout for themselves.\n\nSo, here you go! It's our hope that you are able to use this app to do any or all\nof these things:\n\n- Listen to music 🎧\n- Learn how to use React Suspense\n- See how the features in Apollo Client 3.7 and 3.8 work\n- Try the GraphQL `@defer` directive\n- Experiment with GraphOS by turning a monograph into a supergraph\n- Get some concrete code samples to inspire your own applications\n- Use as a template for reporting bugs\n\n## Maintainers\n\n| Name               | Username                                       |\n| ------------------ | ---------------------------------------------- |\n| Ben Newman         | [@benjamn](https://github.com/benjamn)         |\n| Alessia Bellisario | [@alessbell](https://github.com/alessbell)     |\n| Jeff Auriemma      | [@bignimbus](https://github.com/bignimbus)     |\n| Hugh Willson       | [@hwillson](https://github.com/hwillson)       |\n| Jerel Miller       | [@jerelmiller](https://github.com/jerelmiller) |\n| Lenz Weber-Tronic  | [@phryneas](https://github.com/phryneas)       |\n\n## Spotify API + GraphQL\n\nThis app implements a GraphQL API on top of [Spotify's REST API](https://developer.spotify.com/documentation/web-api/).\nThe GraphQL server aims to mirror the REST API as much as possible, including\nthe field names and returned values. While it's tempting to patch the REST API in\nareas that make it difficult to consume (such as a separate endpoint to check if\na track is in the user's library), this presented a good opportunity to showcase\nhow a developer can use Apollo Client's capabilities to effectively build an app\nwith these kinds of shortcomings.\n\nThere are, however, a few cases where the GraphQL API differs from the REST API.\n\n- This Spotify GraphQL API returns full object types in some areas where Spotify\n  returns \"simplified\" object types. For example, fetching a track via the\n  `/tracks/:trackId` endpoint gives you the full track data, but fetching tracks\n  through the `/albums/:albumId` endpoint gives you a simplified track type. In\n  these cases, the GraphQL API consolidates these distinct types into a the full\n  object type (i.e. `Track`.)\n\n- Paginated fields use a Relay-style [connection type](https://relay.dev/graphql/connections.htm#sec-Connection-Types).\n  This allows the GraphQL API to express edge-specific data and pagination\n  information in a natural way.\n\n- Endpoints that accept a `market` parameter are omitted in the equivalent\n  GraphQL field. This is because, according to the documentation:\n\n  \u003e If a valid user access token is specified in the request header, the country associated with the user account will take priority over this parameter.\n\n  The GraphQL server only works with authenticated users via an access\n  token, so maintaining this parameter was unnecessary overhead.\n\n- The GraphQL serves fields using camelCase. The Spotify REST API returns fields\n  using snake_case. While not strictly enforced in the spec, GraphQL fields are\n  commonly written in camelCase form.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapollographql%2Fspotify-showcase","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapollographql%2Fspotify-showcase","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapollographql%2Fspotify-showcase/lists"}