GraphQL Workshop
Eve Porcello
@eveporcello
eve@moonhighway.com
- Intro to GraphQL
- Understanding the Query Language
- Working with GraphQL Schemas
- Building a GraphQL Server
Agenda
- 7:00AM - Start
- 7:50 - 8:00 - Break
- 8:50 - 9:00 - Break
- 10:00 - End
Timing
- You may know some of this
- This is a workshop
- When you have questions/ideas, always feel free to share
Things to Remember
GraphQL is a query language for your API.
{ }
{ }
Query
Response
DSL
How We Get Data with REST
/lifts/panorama
/trails/ocean-breeze
Noice!
/trails/songstress
/trails/hemmed-slacks
/trails/sandys
[
{
"name": "Panorama",
"type": "gondola",
"capacity": 8,
"status": "open",
"manufacturer": "Garaventa",
"built": 2014,
"summer": true,
"night": false,
"elevation_gain": 2800,
"time": "9 minutes",
"hours": "9:00am - 4:00pm",
"updated": "9:45am",
"trails": [
"/class/api/snowtooth/trails/ocean-breeze",
"/class/api/snowtooth/trails/songstress",
"/class/api/snowtooth/trails/hemmed-slacks",
"/class/api/snowtooth/trails/sandys"
]
}
]
{
"name": "Ocean Breeze",
"lift": [
"/class/api/snowtooth/lifts/panorama"
],
"difficulty": "intermediate",
"status": "open",
"groomed": false,
"snowmaking": false,
"trees": true,
"night": true
}
{
"name": "Hemmed Slacks",
"lift": [
"/class/api/snowtooth/lifts/panorama"
],
"difficulty": "intermediate",
"status": "open",
"groomed": false,
"snowmaking": false,
"trees": true,
"night": false
}
{
"name": "Songstress",
"lift": [
"/class/api/snowtooth/lifts/panorama"
],
"difficulty": "expert",
"status": "closed",
"groomed": false,
"snowmaking": false,
"trees": true,
"night": false
}
{
"name": "Sandys",
"lift": [
"/class/api/snowtooth/lifts/astra-express",
"/class/api/snowtooth/lifts/panorama"
],
"difficulty": "intermediate",
"status": "open",
"groomed": false,
"snowmaking": false,
"trees": false,
"night": false
}
/lifts/panorama
/trails/ocean-breeze
/trails/songstress
/trails/hemmed-slacks
/trails/sandys
How We Get Data with GraphQL
query {
lift(name:"Panorama") {
status
trails {
name
status
}
}
}
{
"data":{
"lift":{
"status":"hold",
"trails": [
{
"name": "Hot Potato",
"status": "open"
},
{
"name": "West Elm",
"status": "closed"
}
]
}
}
}
POST /graphql
Query
https://skiresort.com/graphql
How We Change Data with REST
/lifts/panorama
[
{
"name": "Panorama",
"type": "gondola",
"capacity": 8,
"status": "open",
"manufacturer": "Garaventa",
"built": 2014,
"summer": true,
"night": false,
"elevation_gain": 2800,
"time": "9 minutes",
"hours": "9:00am - 4:00pm",
"updated": "9:45am",
"trails": [
"/class/api/snowtooth/trails/ocean-breeze",
"/class/api/snowtooth/trails/songstress",
"/class/api/snowtooth/trails/hemmed-slacks",
"/class/api/snowtooth/trails/sandys"
]
}
]
PUT
-H 'Content-Type: application/json'
-d { "status": "open" }
How We Change Data with GraphQL
mutation {
setLiftStatus(
name:"Panorama",
newStatus: "hold"
) {
name
newStatus
oldStatus
}
}
{
"data": {
"setLiftStatus": {
"name": "Panorama",
"newStatus": "hold",
"oldStatus": "open"
}
}
}
POST /graphql
Mutation
{ }
Query
Response
{ }
Query
Response
fn( )
fn( )
fn( )
fn( )
fn( )
fn( )
https://pet-library.moonhighway.com
GraphQL is a spec that describes:
A Query Language
A Schema Definition Language
GraphQL Scalar Types
Int
Float
String
Boolean
ID
id: ID!
name: String!
GraphQL Scalar Types
type Photo {
id: ID!
name: String!
url: String!
description: String
rating: Float
private: Boolean!
}
GraphQL Object Types
name: String!
Nullable vs. Non-nullable
description: String
type Query {
totalUsers: Int!
}
Root Queries
type User {
postedPhotos: [Photo!]!
}
Lists
photos: [Photo]
Nullable vs. Non-nullable Lists
photos: [Photo]!
photos: [Photo!]!
Nullable list of nullable values
Non-nullable list of nullable values
Non-nullable list of non-nullable values
Enums
enum PhotoCategory {
PORTRAIT
ACTION
LANDSCAPE
}
One-to-One Connection
type Photo {
postedBy: User!
}
One-to-Many Connection
type User {
postedPhotos: [Photo!]!
}
Many-to-Many Connection
type Student {
schedule: [Course!]!
}
type Course {
students: [Student!]!
}
Root Mutation
type Mutation {
postPhoto: Boolean!
}
Arguments
type Mutation {
postPhoto (name: String!): Photo!
}
Input Types
input PostPhotoInput {
name: String!
category: PhotoCategory=PORTRAIT
description: String
}
Input Types
mutation addPhoto ($input: PostPhotoInput!) {
postPhoto(input: $input) {
id
name
url
}
}
{
"input": {
"name": "Desert Sunset",
"description": "Sunset over Sedona",
"category": "LANDSCAPE"
}
}
Query Variables
Root Subscription
type Subscription {
newPhoto: Photo!
}
Custom Scalars
scalar DateTime
type Photo {
created: DateTime!
updated: DateTime!
}
GraphQL Intro
By Moon Highway
GraphQL Intro
- 1,560