Win back lovely API - GraphQL in Python

Keith Yang, May 2018, PyCon

Win back lovely API
GraphQL in Python

Keith Yang

Web and utilities in Python since 2008

Senior developer in iCHEF F&B POS Co-founder

PyCon Taiwan voluteer since 2012

Chairpersion of PyCon APAC 2015

<< Ready Player One >>

Content Structure

from future import __hope__

What these slides are and are not

iCHEF: Point of Sale platform

At the point of sale, the merchant calculates the amount owed by the customer, indicates that amount, may prepare an invoice for the customer, which may be a cash register printout, and indicates the options for the customer to make payment. -- Point of Sale, Wikipedia

iCHEF R&D Teams

iCHEF machine

Some architecture and deployment in iCHEF

Question 1
what's and where to find
current go-to API implement?

Existed APIs in varieties

Disclaimer: not all caused by RESTful if carefully crafted with OpenAPI Specification (Swagger or Stoplight)

© 2014? 2015, 2016, 2017, 2018

Question 2
what type of fields
will be in response?

No idea until response back


    'status': 123,
    'name': '🐲'

Question 3

Take one

  1. No document
  2. Somewhere outdated document
  3. Code is Law (like 1?)

What we looking for

  1. Consistent interface: flexible and predictable
    • Especially when it's time to open our API to third party
  2. Doable ans scalable: step by step, team by team
  3. Future promising: inspiring and fun

Trend of GraphQL vs REST API vs Python programming: the rise of GraphQL and REST API

🍰 ☕️ 🍕 🍺
in short 🐛

glances of

Look of GraphQL request

/graphql?query={ restaurant(id: "1") \
    { name, category { primary } } }
    'data': {
        'category': {
            'primary': 'Taiwanese Cuisine',
        'name': 'Mazendo'
    'errors': []

A sample of REST request


    'category': {
        'primary': 'Taiwanese Cuisine',
        'second': 'Beef Noodle',
    'name': 'Mazendo'

GraphQL vs REST:
Similar Parts

GraphQL vs REST:
Different Parts

GraphQL vs REST:
Different Parts (cont.)

GraphQL vs REST:
Different Parts (cont.)

HTTP 200

Language agnostic
3-in-1 idea in a GraphQL request

For example, between ECMAScript and Python

Not for API Versioning

GraphQL easy benefits

Development with GraphQL?

  1. Schema
  2. UI and API
  3. Product

Real development with GraphQL

  1. Schema
  2. UI and API
  3. Product

Product design

UI design

query {
    restaurant {
        logoUrl: String!

API desgin

♻️ Schema design

still hard

Naming hazard of fields

GraphQL Schema

GraphQL query schema sample

query {
    restaurant {
        settings {

Common error message format:
errors and data

    "errors": [{
        "message": String,
    "data": {
        "restaurant": {
            "settings": {...}

GraphQL schemas and types

Where it takes time to learn
Grow with spec evolving

GraphQL type language sample

interface Restaurant {
    id: ID!
    name: String!
    categories: [Category]!
type TaiwaneseRestaurant implements Restaurant {
    id: ID!
    name: String!
    categories: [Category]!
    tax_unique_identifier: String

pip install graphene

GroupCreated with Sketch.

GroupCreated with Sketch.

A piece of spec
implemented with Graphene

import graphene
class ReportObject(graphene.ObjectType):
    timestamp = graphene.Int()
    uuid = graphene.UUID()
    type = InventoryTypeGrapheneEnum()
    purchase_amount = graphene.String()
    counting_amount = graphene.Float()

Source code tree of version 2.0.1

GraphQL in iCHEF !=

GraphQL in Yelp

GraphQL in Cousera

GraphQL in IBM

GraphQL in Facebook

GraphQL in iCHEF

How to prompt the idea in the company?


Django serializer

Looks fine to be with graphene-django

Quick graphene-django example

from django.conf.urls import url
from django.contrib import admin

from graphene_django.views import GraphQLView

urlpatterns = [
    url(r'^graphql', GraphQLView.as_view(graphiql=True)),

graphene-django example (cont.)

from import Recipe, RecipeIngredient
from graphene import Node
from graphene_django.types import DjangoObjectType

class RecipeNode(DjangoObjectType):
    class Meta:
        model = Recipe
        interfaces = (Node, )
        filter_fields = ['title','amounts']

graphene-django example (cont.)

from graphene_django.filter import DjangoFilterConnectionField
class Query(object):
    recipe = Node.Field(RecipeNode)
    all_recipes = DjangoFilterConnectionField(RecipeNode)

    recipeingredient = Node.Field(RecipeIngredientNode)
    all_recipeingredients = DjangoFilterConnectionField(

Integration with DRF

It does provide SerializerMutation to help you with DRF. However in our casejust want to write our want serializer mutation due to the varied product spec.

from graphene_django.rest_framework.mutation import \
class MyAwesomeMutation(SerializerMutation):
    class Meta:
        serializer_class = MySerializer

Client Authentication

Numeric detail


To share same query interface between Django ORM, SQLAlchemy, GraphQL backend, and raw dict

Example of queryfilter

dicts = [
    {"age": None},
    {"age": 1},
    {"age": 2},
query_filter = QueryFilter({
    "age": {
        "type": "number",
        "options": {"drop_none": True},
        "min": 0, "max": 1,
assert len(query_filter.on_dicts(dicts)) == 1

Example of queryfilter

import graphene
from queryfilter import (QueryFilter,
    BirthFilterQueryType, TextFilterQueryType,
class UserQueryFilter(graphene.InputObjectType):
    name = TextFilterQueryType()
    birth = BirthFilterQueryType()
    total_login = NumberRangeFilterQueryType()


GraphQL is evolving
even production ready

<< New Release of GraphQL blah >>

I’ve spent 2 years trying to get Apollo Server into prod,
now I’ll no doubt have to make changes.




Q&A 1:
Is it worth to migrate existed APIs?

Q&A 2:
Then HOW?


Start small and stay finish



Just like all other new or different technology you hope to have in the orgazination, it's more of team art and culture. Then it's not always someone's fault, in different condition it's just meant to be failed. It's just that if you didn't try, things surely won't happen. Sometimes it's just that the technology not worthy indead. For this one, I encourage you to try on.

Thank you!