DEV Community

Cover image for All You Ever Wanted To Know About GraphQL
Mark Catalano for TakeShape

Posted on Originally published at takeshape.io

All You Ever Wanted To Know About GraphQL

Co-founder of TakeShape, Andrew Sprouse, presents GraphQL to a JAMstack meetup in New York.

Accompanying Github repo: https://github.com/takeshape/jamstack-meetup-graphql-demo

What is GraphQL?

Schema Definition + Query language + Resolution framework

Schema

  • Provides a strongly typed description of your data
  • Schema Description Language (SDL) is the recommended cross-platform way to specify schema.
enum Title {
    ACTOR
    DIRECTOR
}

type Role {
    characterName: String!
    title: Title
    movie: Movie
}

type Person {
    name: String!
    photo: String
    filmography: [Role]
}

type Movie {
    title: String!
    watched: Boolean
    rating: Float
    poster: String
    actors: [Person]!
    director: Person!
    year: String
}
Enter fullscreen mode Exit fullscreen mode

GraphQL Schema also specifies how you interact with your data with queries and mutations

type Query {
    listMovies: [Movie]
}

type Mutation {
    addMove(title: String): [Movie]
    removeMovie(title: String): [Movie]
}
Enter fullscreen mode Exit fullscreen mode

Query Langauge

Query your data and fetch exactly what you need

query {
    getToWatchList {
        watched
        movie {
            title
            year
            director
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
{
  "data": {
    "getToWatchList": [
      {
        "watched": true,
        "movie": {
          "title": "Top Gun",
          "year": "1985",
          "director": "Tony Scott"
        }
      },
      {
        "watched": true,
        "movie": {
          "title": "Big Trouble in Little China",
          "year": "1986",
          "director": "John Carpenter"
        }
      },
      {
        "watched": true,
        "movie": {
          "title": "The Princess Bride",
          "year": "1987",
          "director": "Rob Reiner"
        }
      },
      {
        "watched": false,
        "movie": {
          "title": "Taxi Driver",
          "year": "1976",
          "director": "Martin Scorsese"
        }
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Mutations

Modify your data

mutation {
    addMovieToWatch(title: "Die Hard") {
        watched
        movieTitle
        movie {
            title
            year
            director
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
{
  "data": {
    "addMovieToWatch": [
      {
        "watched": false,
        "movie": {
          "title": "Taxi Driver",
          "year": "1976",
          "director": "Martin Scorsese"
        }
      },
      {
        "watched": false,
        "movie": {
          "title": "Die Hard",
          "year": "1988",
          "director": "John McTiernan"
        }
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Resolution Framework

  • Each GraphQL implementation provides it own query resolution framework
  • GraphQL.js is the reference implementation
  • Perform query and mutation resolution

Schema (SDL)

type Query {
    getToWatchList: [ToWatch]
}

type Mutation {
    addMovieToWatch(title: String!): [ToWatch]
    removeMovieToWatch(title: String!): [ToWatch]
    markMovieWatched(title: String! watched: Boolean!): [ToWatch]
}
Enter fullscreen mode Exit fullscreen mode

Resolvers

const resolvers = {
    Query: {
        getToWatchList: () => {
            return WatchList.list();
        }
    },

    Mutation: {
        addMovieToWatch(_, {title}) {
            return WatchList.add(title);
        },

        removeMovieToWatch(_, {title}) {
            return WatchList.remove(title);
        },

        markMovieWatched(_, {title, watched}) {
            return WatchList.markWatched(title, watched);
        }
    }
};
Enter fullscreen mode Exit fullscreen mode

Resolvers are also able to resolve dynamically computed fields

Schema (SDL)

type Move {
    title: String
    rating: Float
    poster: String
    actors: String
    director: String 
    year: String
}

type ToWatch {
    movieTitle: String!
    movie: Movie
    watched: Boolean!
}
Enter fullscreen mode Exit fullscreen mode

Resolvers

const resolvers = {
    ToWatch: {
        async movie(toWatch) {
            const info = await fetchMovieInfo(toWatch.movieTitle);
            return info ? {
                title: info.Title,
                rating: info.imdbRating,
                poster: info.Poster,
                year: info.Year,
                actors: info.Actors,
                director: info.Director
            } : null
        }
    }
};
Enter fullscreen mode Exit fullscreen mode

Top comments (0)