How to migrate

from Django REST Framework
to GraphQL API

I am…

  • Igor Davydenko
  • Python / JavaScript developer
  • Have 2 projects with GraphQL at production

Agenda, kind of

  • What is GraphQL? GraphiQL?
  • GraphQL & Python
  • Django Graphene
  • Migragion itself
  • Advanced topics

GraphQL

A Query Language for your API

A Query Language for your API

  • Describe your data
  • Make query
  • Get predictable results

A Query Language for your API

  • Get many resources in one request
  • Evolve your API without versions
  • Powerful developer tools

GraphQL Query Language

{
  allTeams {
    nodes {
      name
      slug
      conferenceSlug
    }
  }
}

GraphQL Query Language

{
  teams: allTeams(condition: {conferenceSlug: "afc"}, orderBy: NAME_ASC) {
    nodes {
      name
      slug
    }
  }
}

GraphQL Query Language

query conferenceTeams($slug: String!) {
  teams: allTeams(condition: {conferenceSlug: $slug}, orderBy: NAME_ASC) {
    nodes {
      ...TeamDetails
      divisionSlug
    }
  }
}

fragment TeamDetails on Team {
  name
  slug
}

Powerful developer tools. GraphiQL

GraphiQL

Powerful developer tools. GraphiQL

GraphiQL

GraphQL & Python

graphql-core

Basic GraphQL implementation for Python

graphql-core-next

Python 3.6+ port of latest GraphQL.js
reference implementation of GraphQL

graphene

GraphQL framework for Python

graphene-django

GraphQL framework for Django

graphene-sqlalchemy

GraphQL framework for SQLAlchemy

Why switch to the
GraphQL?

Get aboard to hype train

Frontend simplification

Viva la Apollo Client!

Requests minification

Requests minifcation

{
  currentSeason: seasonByYear(year: 2018) {
    ...SeasonDetails
  }
  tweets: allTweets {
    nodes {
      ...TweetDetails
    }
  }
  teams: allTeams {
    nodes {
      ...TeamDetails
    }
  }
}

Typed Schema

postgraphile

Previously postgraphql

npx postgraphile -c <DATABASE_URL>

postgraphile

Does it work for you?
Now what?

Django Graphene

app/schema.py

from graphene_django.types import DjangoObjectType

from .models import Category


class CategoryType(DjangoObjectType):
    class Meta:
        model = Category

app/schema.py

class Query(object):
    all_categories = graphene.List(CategoryType)

    def resolve_all_categories(self, info, **kwargs):
        return Category.objects.all()

project/schema.py

from graphene import ObjectType

from app.schema import Query as AppQuery

class Query(AppQuery, ObjectType):
    pass

schema = graphene.Schema(query=Query)

project/settings.py

INSTALLED_APPS = [
    ...,
    'graphene_django',
]
...
GRAPHENE = {
    'SCHEMA': 'project.schema.schema',
}

project/urls.py

from graphene_django.views import GraphQLView

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

Query vs Node vs Interface

  • Interface (abstract Node) is Interface
  • Node is ObjectType or DjangoObjectType
  • Query is object

Fields

  • Enums
  • Scalars (strings, ints, floats, booleans, ID, dates, datetimes, times, JSON strings) + Custom scalars
  • Lists (and not-null lists)
  • Unions

Resolvers

  • Field resolvers
  • Middleware resolvers
  • Dataloader

Advanced

Integration with DRF

You can use Django REST Framework serializer for mutations in GraphQL

Authentication

  • PrivateGraphQLView
  • Specify fields to use (only, exclude)
  • User-based query filtering via field resolver
  • Filtering ID-based node access
  • Setting up authentication in middleware

Mutations

  • Create / update models via GraphQL
  • Can be integrated with Django Forms as well

File Uploads

- Use base64, Luke
- But why…

Conclusion?

Hm…

It is hard

To develop GraphQL in Python

But hopefully

graphql-core-next will be the case

Questions?

Twitter: @playpausenstop
GitHub: @playpauseandstop