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
}
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]
}
Query Langauge
Query your data and fetch exactly what you need
query {
getToWatchList {
watched
movie {
title
year
director
}
}
}
{
"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"
}
}
]
}
}
Mutations
Modify your data
mutation {
addMovieToWatch(title: "Die Hard") {
watched
movieTitle
movie {
title
year
director
}
}
}
{
"data": {
"addMovieToWatch": [
{
"watched": false,
"movie": {
"title": "Taxi Driver",
"year": "1976",
"director": "Martin Scorsese"
}
},
{
"watched": false,
"movie": {
"title": "Die Hard",
"year": "1988",
"director": "John McTiernan"
}
}
]
}
}
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]
}
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);
}
}
};
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!
}
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
}
}
};