Skip to content

NeoHW/music-matcher

Repository files navigation

Music Matcher — Learning GraphQL with C# & Hot Chocolate

This is a project implementing GraphQL in .NET 6+ using the Hot Chocolate library. This project integrates with the Spotify Web API and serves as a sandbox for exploring advanced GraphQL patterns, from schema design to resolver chains and performance optimization.


Project Structure

Odyssey.MusicMatcher/
├── Types/
│   ├── Query.cs                 # Top-level query definitions
│   ├── Mutation.cs              # GraphQL mutations (write operations)
│   ├── Playlist.cs              # GraphQL object type for Playlists
│   ├── Track.cs                 # Track type (songs)
│   ├── Artist.cs                # Artist type (if extended)
│   ├── AddItemsToPlaylistInput.cs
│   ├── AddItemsToPlaylistPayload.cs
├── Program.cs                   # Entry point and service setup

Key GraphQL Concepts Explored

1. Schema Definition & Type Mapping

Using attributes like [GraphQLDescription] and [ID], each C# class (like Playlist, Track) is mapped to a GraphQL object type.


2. Queries

All read operations are exposed via Query.cs. Example:

{
  featuredPlaylists {
    id
    name
    description
  }
}

This triggers the FeaturedPlaylists() method which calls Spotify’s REST API, transforms the data, and returns a list of Playlist objects.


3. Mutations

Write operations are defined in Mutation.cs. Example:

mutation {
  addItemsToPlaylist(input: {
    playlistId: "xyz",
    uris: ["spotify:track:abc", "spotify:track:def"]
  }) {
    success
    message
    playlist {
      name
    }
  }
}

This triggers a REST API call to Spotify to add items to a playlist.


4. Resolver Chains

In GraphQL, each nested field can trigger its own resolver. For example:

{
  featuredPlaylists {
    name
    tracks {
      name
      uri
    }
  }
}
  • The top-level resolver fetches simplified playlist data.
  • When tracks is requested, the resolver method Tracks() is called on each Playlist instance.
  • This is where resolver chaining happens — each level pulls data only if requested.

5. GraphQL to REST Bridge

This app doesn't use a backing database — it uses Spotify’s REST API as the data source, wrapped in GraphQL. For instance:

  • GetFeaturedPlaylistsAsync()
  • GetPlaylistAsync(id)
  • GetPlaylistsTracksAsync(id)

These are mapped to GraphQL queries using model transformation inside resolvers.


The N+1 Problem

If a query requests playlists and their tracks, and each tracks resolver fetches data individually, this results in:

  • 1 request to fetch playlists
  • N requests (one per playlist) to fetch tracks

This is inefficient, especially with large datasets.


Solution: DataLoaders

Use Hot Chocolate's DataLoader to batch requests for tracks:

public Task<List<Track>> Tracks(
  [Service] PlaylistTracksDataLoader dataLoader
)
{
    return dataLoader.LoadAsync(Id);
}

The DataLoader batches all calls to Tracks() and performs a single REST call to fetch all track data at once — solving the N+1 problem efficiently.


Learnings

  • How to design intuitive and descriptive GraphQL schemas.
  • Difference between properties and methods as GraphQL resolvers.
  • How resolver chaining works and why it matters for performance.
  • Best practices for exposing a REST API through GraphQL.
  • Importance of error handling using GraphQLException and custom error codes.
  • How mutations work and return standardized payloads with code, success, and message.

Tech Stack

  • .NET 6
  • Hot Chocolate (GraphQL for .NET)
  • Spotify Web API
  • C# 10
  • Apollo Studio (used for running GraphQL queries)

Running the Project

  1. Add your Spotify API credentials to a .env file:
CLIENT_ID=your_client_id
CLIENT_SECRET=your_client_secret
  1. Run the app:
dotnet run
  1. Open Apollo Studio Explorer or Postman and hit:
http://localhost:5059/graphql

Next Steps

  • Add DataLoader to batch track fetching.
  • Explore authorization and user-specific data.
  • Add pagination and filtering to queries.
  • Create a frontend UI to consume this API.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages