GraphQL

Better way to build your API

me@jaro.lt     |     @chompomonim    |    +JaroSatkevic

  • About GraphQL with full stack in mind
  • Short history of GraphQL
  • Simple python graphql server
  • GraphQL server in real life - tips & tricks

AGENDA

REST is cool, but...

Let's get:

  • SW Hero
  • His home planet
  • His starship
GET /hero/1
GET /hero/1/homeworld
GET /hero/1/starships
GET /hero/1?include=starships,homeworld

OR

OR

GET /hero/1
GET /starships?heroId=1
GET /planets?heroId=1

Over-fetching

Hard to design "proper" api

Documentation hell

How many queries do we need to render this view? 

What is GraphQL?

A query language for your API

Short facts:

  • Invented at Facebook 5 years ago
  • OpenSourced in summer 2015
  • Already used at Github, Pinterest, Coursera, Shopify, Intuit, WIX and many more ...
{
  hero(id: "1") {
    name
    birthYear
    eyeColor
    gender
    homeworld {
      name
      population
    }
    starships (first: 2) {
      name
      model
    }
  }  
}
GET /hero/1?include=name,birthYear,gender
GET /hero/1/homeworld
GET /starships?heroId=1&include=name,model
type Person {
     name: String!
     gender: String
     eyeColor: String
     birthYear: String
     homeplanet: Homeplanet
     starships: [Starships]
}

type Starship {
     name
     model
     speed
}

Strictly typed

{
  person(personID: "1") {
    name
    birthYear
    eyeColor
    gender
    homeworld {
      name
      population
    }
    starships (first: 1) {
      name
      model
    }
  }  
}
{
  "data": {
    person: {
      "name": "Luke Skywalker",
      "birthYear": "19BBY",
      "eyeColor": "blue",
      "gender": "male",
      "homeworld": {
        "name": "Tatooine",
        "population": 200000
      },
      "starships": [
        {
            "name": "X-wing",
            "model": "T-65 X-wing"
        }
      ]
    }
  }
}

Query

Response

Anyway, why GraphQL?

Features I wanted as UI developer

  • Fast data queries with all&only needed data
  • Data caching, to avoid refetching
  • Allow to work offline
  • Specify queries, parses data
  • Easy to paginate
  • Execute mutations, with cache and pagination

GraphQL clients

Relay

GraphQL on server

A lot of libraries

http://graphql.org/code/

from sanic import Sanic
from sanic.response import json

app = Sanic()

@app.route("/", methods=['POST'])
async def post_root(request):
    return json({"hello": "world"})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=4000)
from sanic import Sanic
from sanic.response import json

app = Sanic()

#### GraphQL schema
import graphene

class Query(graphene.ObjectType):
    labas = graphene.String(description='A typical hello world')

    def resolve_labas(self, args, context, info):
        return 'Rytas'

schema = graphene.Schema(query=Query)
####

@app.route("/", methods=['POST'])
async def post_root(request):
    result = schema.execute(request.json['query'])
    return json(result.data)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=4000)

Some tricky places you should think about

How many queries into database?

{
  person(personID: "1") {
    name
    birthYear
    eyeColor
    gender
    homeworld {
      name
      population
    }
    starships (first: 10) {
      name
      model
    }
  }  
}

How big is response for this request?

{
  persons {
    name
    birthYear
    eyeColor
    gender
    homeworld {
      name
      population
    }
    starships (first: 10) {
      name
      model
      passangers {
        name
        gender
        homeworld {
          name
        }
      }
    }
  }  
}

Tips & tricks

  • Use limits on bigger amount of data (avoid asking for whole DB)
  • Define schema first
  • Read carefully full specification, it may help
  • Prepare for caching your most advanced queries

Questions

Example app: https://github.com/chompomonim/python-graphql-example

me@jaro.lt     |     @chompomonim    |    +JaroSatkevic

Made with Slides.com