Skip to content

jacobduijzer/graphql-is-cooler-than-rest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GraphQL is cooler than (the) REST!

This repository is used to demonstrate GraphQL, using HotChocolate GraphQL, a .NET library for building GraphQL APIs.

The goal of the application is simple: you can view movies and their ratings, and get snack recommendations based on the movie you're watching. This is how the architecture looks like:

Container diagram

Features

  • Queries: Fetch movies, with ratings and snack recommendations.
  • Mutations: Add, update or delete ratings.
  • Subscriptions: Get notified when movie is rated.
  • Resolvers: Fetch snack recommendations based on movie.
  • Data Loaders: Fetch movie ratings more efficiently.
  • Authentication & Authorization: Secure login, review management, and role-based access control.
  • Front-end demo apps:
    • Vue (JavasScript GraphQL Client)
    • Razor Pages (.NET Strawberry Shake GraphQL Client)

Slides

Slides of my talk are available here.

Getting started

Prerequisites

Installation

  1. Clone the repository
git clone https://github.com/jacobduijzer/graphql-is-cooler-than-rest.git
cd graphql-is-cooler-than-rest
  1. Install dependencies
dotnet restore
  1. Run the application
dotnet run --project src/Snackflix.AppHost --no-restore
  1. Open the GraphQL Playground by clicking on the URL in the console.
  2. Wait for all resources to start, then open the Api url in your browser, by clicking on the URL of the SnackFlix.Api project (see image). API Project

Movies

A simple list with all available movies:

query movies {
  movies {
    title
  }
}

A list with all movies, including the ratings and snack recommendations:

query allMoviesWithRatingsAndSnackRecommendations {
  movies {
    title
    snacks
    ratings {
      rating
    }
  }
}

The same query, but now using a data resolver, to make the queries more efficient. Look at the tracings on the Aspire dashboard to see the difference:

query moviesWithOptimizedRatings {
  movies {
    title
    snacks
    optimizedRatings {
      rating
    }
  }
}

A single movie can be viewed with a parameterized query:

query movie {
  movie(id: 1) {
    title
    snacks
    ratings {
      rating
    }
  }
}

TODO List

  • Queries
    • Movies
    • Snack recommendations
    • Ratings
  • Mutations
    • Add rating for movie
  • Subscriptions
    • Rating added for movie
  • Resolvers
    • Snack recommendations
    • Ratings
  • Data Loaders
    • Movie ratings
  • Authentication & Authorization
    • Login
    • Add Review (customer)
    • Edit review (only my own reviews)
    • Remove (admin, roles)
    • Fine-grained (account id on review)
  • Clients
    • Strawberry Shake
    • Apollo Client

Movies

Reviews / Ratings

Accounts

query movies {
    # all genres as a list
    genres

    # all movie titles and id's
    a: movies {
        id
        title
    }

    # the information of the movie with id 1
    movie(id: 1) {
        title
        year
        genres
        ratings
        description
    }

    # the titles of movies with genre Action
    moviesByGenre(genre: "Action") {
        title
    }

    # all movie titles, filtered by genre, should equal "Action"
    b: movies(where:  {
        genres:  {
            some:  {
                eq: "Action"
            }
        }
    }) {
        title
    }
}

Links