• Stars
    star
    126
  • Rank 284,543 (Top 6 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created almost 2 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Spotify clone that showcases the Apollo GraphQL platform.
Apollo Client

React + Apollo Spotify Showcase

Screenshot 2023-03-07 at 5 13 26 PM

Architecture

The 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).

The Apollo Router routes incoming traffic from the client application and integrates with GraphOS to receive schema updates and report usage metrics.

graph LR;

subgraph "Netlify"
  web["Website\n(client app)"]
end

subgraph "Railway"
  router{"Apollo Router"}
  playbackSubgraph["Playback Subgraph\n(subriptions/mutations)"]
  spotifySubgraph["Spotify Subgraph\n(queries)"]
end

subgraph "Apollo"
  schema["Schema Pipeline"]
  usage["Usage Reporting"]
end

subgraph "Spotify"
  spotifyREST[Spotify REST API]
end

web <--> router
router <-->|Schema Updates\nUsage Reporting| Apollo
router <--> spotifySubgraph
router <--> playbackSubgraph
playbackSubgraph <--> spotifyREST
spotifySubgraph <--> spotifyREST

classDef spotifyBox color:#FFFFFF,fill:#1DB954,stroke:#FFFFFF,stroke-width:2px;
classDef netlifyBox color:#014847,fill:#FFFFFF,stroke:#32e6e2,stroke-width:2px;
classDef railwayBox color:#000000,fill:#FFFFFF,stroke:#000000,stroke-width:2px;
classDef apolloBox color:#3f20ba,fill:#FFFFFF,stroke:#3f20ba,stroke-width:2px;

class Spotify spotifyBox
class Netlify netlifyBox
class Netlify-Function netlifyBox
class Railway railwayBox
class Apollo apolloBox

*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*

Getting started

What do you want to do next with this demo app?

I want to play around with the public version of the demo

  1. Visit the public Apollo Explorer instance to interact with the graph (No GraphOS account required)
  • Query the graph (Spotify account required) - OAuth workflow with be initiated from Apollo Explorer to login to our Spotify account to run any operation
    • Try having your Spotify app playing on your phone or desktop and then run this mutation
  • View the graph's schema

I want to re-create this demo in my GraphOS account

Note: To create graphs, you must have the Org Administrator or Graph Administrator role for your GraphOS organization.

  1. Clone this repo.

  2. Create a personal API key.

  3. Run the script below using your personal API key.

    AUTH={YOUR_API_KEY} npm run graphos-demo

    If you have multiple organizations, the script will prompt you to select which organization the graph should be in.

I want to run the client app locally

  1. Clone this repo.

  2. From the root of the folder, install the dependencies.

    npm install
  3. From the root of the folder, start the client app.

    npm start
  4. Visit the website at http://localhost:3000.

By 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).

Local 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).

I want to run the backend locally - using Docker

You will need a GraphOS organization with an Enterprise plan or Enterprise trial plan to utilize all the GraphOS features.

  1. Follow the steps in the "I want to re-create this demo in my GraphOS account" section above.

  2. Find the newly-created graph in GraphOS Studio. Create a Graph API key from the Settings page, with the default "Graph Admin" permissions.

  3. Create a .env file at the root of this repository and add in the following variables:

    APOLLO_GRAPH_REF={YOUR_DEMO_GRAPH_ID}@main
    APOLLO_KEY={YOUR_GRAPH_API_KEY}
    CALLBACK_URL=http://router:4000
    
  4. Start the router and subgraphs:

    npm run docker:run
    
  5. 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.

    # persisted_queries:
    #   enabled: true
    #   safelist:
    #     enabled: true
    #     require_id: false

    Re-run the docker:run command.

I want to run the backend locally

You will need a GraphOS organization with an Enterprise plan or Enterprise trial plan to utilize all the GraphOS features.

  1. Follow the steps in the "I want to re-create this demo in my GraphOS account" section above.

  2. Find the newly-created graph in GraphOS Studio. Create a Graph API key from the Settings page, with the default "Graph Admin" permissions.

  3. Create a .env file at the root of this repository and add in the following variables:

    APOLLO_GRAPH_REF={YOUR_DEMO_GRAPH_ID}@main
    APOLLO_KEY={YOUR_GRAPH_API_KEY}
    CALLBACK_URL=http://router:4000
    
  4. Download the latest router binary to the router folder.

  5. Build and start the subgraphs. In the root of the project, run:

    npm run build
    
    npm run start:spotify
    

    and in another terminal:

    npm run start:playback
    

    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.

  6. In a new terminal, start the router:

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

    # persisted_queries:
    #   enabled: true
    #   safelist:
    #     enabled: true
    #     require_id: false

    Restart the router to run it with the latest config changes.

Debugging the subgraphs or client locally with VS Code

There 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:

Subgraph responsibilities

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.

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.

Feedback survey

If you used the React + Apollo Spotify Showcase and have two minutes then we'd really appreciate it if you filled out this survey - it really helps us improve!

Exploring the codebase?

If you're exploring the codebase and not sure where to get started, try the following:

Client

  • client/src/router.tsx - This defines all routes used in the app. To view the source code for a given route, follow the import for the route component.
  • client/src/index.tsx - This is the entry point to the client app. This defines the providers used in the app.

Server

  • server.ts - This defines the Apollo GraphQL server used to serve the Spotify GraphQL schema.
  • server/src/resolvers/ - This defines the resolvers used to resolve types and fields in the schema. The file names correspond to their respective types in the schema.
  • server/src/dataSources/spotify.ts - Defines the Spotify client used to make REST calls to Spotify's REST API.

About

Apollo Client's newest features unlock powerful UI development capabilities when used with React 18. Using Suspense via useSuspenseQuery is one such capability, as is useBackgroundQuery. Both of these will be shipped in 3.8.0. These hooks, along with the already-available useFragment hook and the GraphQL @defer directive, comprise a toolkit for the UI developer to implement the render-as-you-fetch pattern throughout the component tree.

@jerelmiller started building this application while building useSuspenseQuery in an effort to dogfood the changes with a non-trivial app. Apollo Client and GraphQL are built to be both approachable and scalable; to-do apps are the former but not the latter. A Spotify clone - and it really is a clone (👀 that CSS) - offered a much more robust proving ground for the functionality we were building. As the team used it more and more, we decided that if we open-sourced it then the community could use it to try things out for themselves.

So, here you go! It's our hope that you are able to use this app to do any or all of these things:

  • Listen to music 🎧
  • Learn how to use React Suspense
  • See how the features in Apollo Client 3.7 and 3.8 work
  • Try the GraphQL @defer directive
  • Experiment with GraphOS by turning a monograph into a supergraph
  • Get some concrete code samples to inspire your own applications
  • Use as a template for reporting bugs

Maintainers

Name Username
Ben Newman @benjamn
Alessia Bellisario @alessbell
Jeff Auriemma @bignimbus
Hugh Willson @hwillson
Jerel Miller @jerelmiller
Lenz Weber-Tronic @phryneas

Spotify API + GraphQL

This app implements a GraphQL API on top of Spotify's REST API. The GraphQL server aims to mirror the REST API as much as possible, including the field names and returned values. While it's tempting to patch the REST API in areas that make it difficult to consume (such as a separate endpoint to check if a track is in the user's library), this presented a good opportunity to showcase how a developer can use Apollo Client's capabilities to effectively build an app with these kinds of shortcomings.

There are, however, a few cases where the GraphQL API differs from the REST API.

  • This Spotify GraphQL API returns full object types in some areas where Spotify returns "simplified" object types. For example, fetching a track via the /tracks/:trackId endpoint gives you the full track data, but fetching tracks through the /albums/:albumId endpoint gives you a simplified track type. In these cases, the GraphQL API consolidates these distinct types into a the full object type (i.e. Track.)

  • Paginated fields use a Relay-style connection type. This allows the GraphQL API to express edge-specific data and pagination information in a natural way.

  • Endpoints that accept a market parameter are omitted in the equivalent GraphQL field. This is because, according to the documentation:

    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.

    The GraphQL server only works with authenticated users via an access token, so maintaining this parameter was unnecessary overhead.

  • The GraphQL serves fields using camelCase. The Spotify REST API returns fields using snake_case. While not strictly enforced in the spec, GraphQL fields are commonly written in camelCase form.

More Repositories

1

apollo-client

🚀  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
TypeScript
19,300
star
2

apollo-server

🌍  Spec-compliant and production ready JavaScript GraphQL server that lets you develop in a schema-first way. Built for Express, Connect, Hapi, Koa, and more.
TypeScript
13,522
star
3

react-apollo

♻️ React integration for Apollo Client
JavaScript
6,887
star
4

apollo-ios

📱  A strongly-typed, caching GraphQL client for iOS, written in Swift.
Swift
3,737
star
5

apollo-kotlin

🤖  A strongly-typed, caching GraphQL client for the JVM, Android, and Kotlin multiplatform.
Kotlin
3,382
star
6

apollo-tooling

✏️ Apollo CLI for client tooling (Mostly replaced by Rover)
TypeScript
3,042
star
7

apollo

🚀 Open source tools for GraphQL. Central repo for discussion.
JavaScript
2,626
star
8

graphql-tag

A JavaScript template literal tag that parses GraphQL queries
TypeScript
2,275
star
9

graphql-subscriptions

📰 A small module that implements GraphQL subscriptions for Node.js
TypeScript
1,567
star
10

subscriptions-transport-ws

🔃 A WebSocket client + server for GraphQL subscriptions
TypeScript
1,524
star
11

apollo-client-devtools

Apollo Client browser developer tools.
TypeScript
1,481
star
12

apollo-link

🔗 Interface for fetching and modifying control flow of GraphQL requests
TypeScript
1,438
star
13

apollo-link-state

✨ Manage your application's state with Apollo!
TypeScript
1,405
star
14

apollo-cache-persist

🎏 Simple persistence for all Apollo Cache implementations
TypeScript
1,368
star
15

fullstack-tutorial

🚀 The Apollo platform tutorial app
TypeScript
1,233
star
16

eslint-plugin-graphql

🚦 Check your GraphQL query strings against a schema.
JavaScript
1,194
star
17

router

A configurable, high-performance routing runtime for Apollo Federation 🚀
Rust
793
star
18

apollo-link-rest

Use existing REST endpoints with GraphQL
TypeScript
783
star
19

federation

🌐  Build and scale a single data graph across multiple services with Apollo's federation gateway.
TypeScript
659
star
20

apollo-fetch

🐶 Lightweight GraphQL client that supports middleware and afterware
TypeScript
576
star
21

apollo-rs

Spec compliant GraphQL Tools in Rust.
Rust
566
star
22

reason-apollo

Reason binding for Apollo Client and React Apollo
Reason
552
star
23

federation-demo

Federation 2 supersedes this demo and this example is no longer the newest. See https://www.apollographql.com/docs/federation/ for migration steps!
JavaScript
502
star
24

ac3-state-management-examples

✨ Learn Apollo Client 3's state management best practices
TypeScript
493
star
25

apollo-tracing

A GraphQL extension for performance tracing
475
star
26

apollo-client-nextjs

Apollo Client support for the Next.js App Router
TypeScript
446
star
27

persistgraphql

A build tool for GraphQL projects.
TypeScript
424
star
28

rover

The CLI for Apollo GraphOS
Rust
404
star
29

gatsby-theme-apollo

💜 Themes that we use to build Gatsby sites at Apollo
JavaScript
371
star
30

apollo-link-persisted-queries

Persisted Query support with Apollo Link
TypeScript
307
star
31

xcode-graphql

🛠 Xcode add-ons that add syntax highlighting for GraphQL query document files
Shell
276
star
32

apollo-studio-community

🎡  GraphQL developer portal featuring an IDE (Apollo Explorer), auto-documentation, metrics reporting, and more. This repo is for issues, feature requests, and preview docs. 📬
249
star
33

federation-jvm

JVM support for Apollo Federation
Java
247
star
34

supergraph-demo-fed2

🍿 Supergraph demo for Federation 2 and Apollo Router
Shell
162
star
35

principled-graphql

📈 Best practices for implementing and scaling a data graph
JavaScript
148
star
36

apollo-cache-control

A GraphQL extension for cache control
146
star
37

supergraph-demo

🍿 Compose subgraphs into a Federation v1 supergraph at build-time with static composition to power a federated graph router at runtime.
Shell
135
star
38

apollo-feature-requests

🧑‍🚀 Apollo Client Feature Requests | (no 🐛 please).
130
star
39

meteor-integration

🚀 meteor add apollo
JavaScript
108
star
40

frontpage-ios-app

📄 Apollo "hello world" app, for iOS
Swift
101
star
41

space-kit

👩‍🚀 Home base for Apollo's design system: https://space-kit.netlify.com
TypeScript
88
star
42

apollo-scalajs

Use Apollo GraphQL from Scala.js apps!
Scala
88
star
43

invariant-packages

Packages for working with invariant(condition, message) assertions
TypeScript
88
star
44

apollo-federation-subgraph-compatibility

A repo to test subgraph libraries compatibility with the Apollo Federation Specification
TypeScript
77
star
45

starwars-server

JavaScript
73
star
46

blog

📝 Blog website built with Wordpress and Gatsby
JavaScript
68
star
47

iOSTutorial

The tutorial application for the Apollo iOS SDK
Swift
68
star
48

odyssey-lift-off-part1

JavaScript
64
star
49

federation-jvm-spring-example

Apollo Federation JVM example implementation using Spring for GraphQL
Java
64
star
50

vscode-graphql

Apollo GraphQL VS Code extension
TypeScript
55
star
51

apollo-kotlin-tutorial

The code for the Apollo Kotlin Tutorial
Kotlin
52
star
52

docs-examples

Example code supporting the Apollo docs
TypeScript
50
star
53

docs

📚 Apollo's docs framework
MDX
42
star
54

apollo-kotlin-2-tutorial

The code for the Apollo Android Tutorial
Kotlin
38
star
55

iOSCodegenTemplate

A template for the code you need to set up to get Swift Scripting up and running.
Swift
38
star
56

datasource-rest

A caching data source for REST APIs
TypeScript
37
star
57

apollo-workbench-vscode

Apollo Workbench is a design tool that facilitates planning changes to your supergraph. It enables you to understand the overall composition and execution of any given query at design time.
TypeScript
37
star
58

apollo-utils

Monorepo of common utilities related to Apollo and GraphQL
TypeScript
35
star
59

graphql-testing-library

Testing utilities that encourage good practices for apps built with GraphQL.
TypeScript
35
star
60

federation-rs

Contains source code for Apollo Federation's Rust<--> JavaScript interop
Rust
34
star
61

react-apollo-error-template

Apollo Client issue reproduction.
JavaScript
33
star
62

embeddable-explorer

TypeScript
32
star
63

federation-migration-example

🚀Example app migrated from schema stitching to Apollo federation
JavaScript
32
star
64

odyssey-lift-off-part5-server

Odyssey Lift-off V - Server - Course Companion App
JavaScript
31
star
65

odyssey-lift-off-part5-client

Odyssey Lift-off V - Client - Course Companion App
JavaScript
28
star
66

GraphiQL-Subscriptions-Fetcher

GraphiQL's fetcher that supports GraphQL-Subscriptions with the `subscriptions-transport-ws` package
TypeScript
28
star
67

supergraph-demo-k8s-graph-ops

Archived: GitOps config repo for an Apollo GraphQL federated graph with a supergraph router and subgraph services deployed to Kubernetes.
Shell
28
star
68

apollo-ios-dev

Apollo iOS Development Repo
Swift
28
star
69

apollo-ios-pagination

Swift
26
star
70

odyssey-lift-off-part2

Odyssey Lift-off Part 2 Course Companion App
JavaScript
26
star
71

spacex

A re-creation of https://github.com/SpaceXLand/api
TypeScript
21
star
72

apollo-graphql-stream-scenes

This is used for hosting streaming scenes for OBS - for Apollo GraphQL stream
JavaScript
19
star
73

federation-next

Moved to the Router repository
Rust
19
star
74

subgraph-template-typescript-apollo-server-boilerplate

A template for a minimal setup Apollo Server 4.x using TypeScript
TypeScript
17
star
75

federation-hotchocolate

HotChocolate support for Apollo Federation
C#
16
star
76

odyssey-lift-off-part3

Odyssey Lift-off Part 3 Course Companion App
JavaScript
15
star
77

odyssey-voyage-I

JavaScript
14
star
78

typescript-repo-template

A template for TypeScript projects with pre-configured tooling
TypeScript
14
star
79

subgraph-template-typescript-apollo-server

A Typescript template for Apollo Server as a subgraph using Apollo Federation
TypeScript
13
star
80

next-apollo-example

Template for creating Apollo Client + Next.js reproductions
JavaScript
13
star
81

community

Apollo community guidelines
JavaScript
13
star
82

design-principles

Where we are defining and collaborating on our Apollo internal design principles (individually and collaboratively). This is a public repo, but intended only for use by Apollo employees.
13
star
83

odyssey-lift-off-part4

Odyssey Lift-off Part 4 Course Companion App
JavaScript
12
star
84

core-schema-js

Typescript library for processing core schemas
TypeScript
12
star
85

apollo-client-swift-playground

Swift
11
star
86

apollo-ios-codegen

Apollo iOS Code Generation
Swift
11
star
87

test-span

Rust
11
star
88

specs

Apollo Library of Technical Specifications
CSS
10
star
89

router-template

A general purpose self-hosted Apollo Router template connected to GraphOS
Dockerfile
10
star
90

apollo-midnight

A VS Code color theme based on Apollo Studio Explorer color palette.
9
star
91

serde_json_bytes

a JSON Value object with strings backed by Bytes, parsed by serde_json
Rust
8
star
92

hack-the-supergraph

JavaScript
8
star
93

subgraph-template-rust-async-graphql

A boilerplate template project for building a subgraph with async-graphql
Rust
8
star
94

router-biscuit-plugin

⚠️experimental⚠️ plugin for the router using Biscuit tokens for authorization
Rust
7
star
95

devhub

🔭 Explore all the latest resources for building apps with Apollo
JavaScript
7
star
96

client-router-e2e-tests

Apollo Client ↔️ Router E2E Test Suite
JavaScript
7
star
97

odyssey-lift-off-lab

Odyssey Lift-off Lab starter repo
JavaScript
7
star
98

graphchat

TypeScript
6
star
99

introspector-gadget

GraphQL introspection utilities
Rust
6
star
100

zen-observable-ts

Thin wrapper around zen-observable and @types/zen-observable, to support ESM exports
JavaScript
6
star