Introduction à GraphQL avec Python
Tout comme nous l'avions fait pour la mise en place d'une API Rest en Python avec Falcon, nous allons aujourd'hui mettre en place une application GraphQL avec le framework Django.
A quoi sert GraphQL?
Publié en Open Source par Facebook en 2015, GraphQL est une syntaxe décrivant la procédure à suivre pour demander des données. Elle est généralement utilisée pour charger des données d’un serveur vers un client. GraphQL a trois caractéristiques principales:
- Il permet au client de spécifier exactement les données dont il a besoin
- Il facilite l'agrégation des données provenant de plusieurs sources.
- GraphQL n'est pas lié à un moteur de stockage spécifique
Concurrent direct des API REST, GraphQL permet en un seul point de récupérer un ensemble de données provenant de différentes sources. En considérant une application qui permet de récupérer auteurs et articles de blog il faudrait considérer une url pour récupérer les auteurs, une autre pour récupérer les articles de blog. Avec GraphQL, une seule URL est nécessaire comme nous allons le voir.
Mise en place de Django et Graphene
Afin de comparer plus facilement API REST et GraphQL, nous allons reprendre le modèle de gestion de interventions utilisé dans notre article consacré aux API avec Falcon. Nous utilisons Django comme framework et Graphene, une librairie pour construire des API GraphQL.
Dans un terminal, créez un nouvel environnement et activez le:
virtualenv -p python3 intervention_with_graphql
source intervention_with_graphql/bin/activate
Passons désormais à l'installation des bibliothèques nécessaires:
pip install django graphene-django
django-admin startproject demo_graphql
cd demo_graphql
python manage.py migrate
python manage.py runserver
À ce stade, notre projet est créé et l'url http://127.0.0.1:8000/ présente la page par défaut de Django.
Une dernière configuration nous permet d'utiliser la librairie graphene dans notre application. Dans le fichier demo_graphql/settings.py
, recherchez la variable INSTALLED_APPS
et ajoutez graphene_django
:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'graphene_django',
]
GRAPHENE = {
'SCHEMA': 'demo_graphql.schema.schema',
}
Mise en place d'une application de gestion des interventions
Dans le précédent chapitre, nous avons mis en place la structure de notre projet grâce à Django. Nous allons donc désormais créer une application pour gérer les interventions, une autre pour les intervenants.
Commençons par créer une application pour les interventions
python manage.py startapp interventions
Un nouveau répertoire a été créé avec un ensemble de fichiers. Il nous faut désormais définir notre modèle:
from django.db import models
class Intervention(models.Model):
title = models.CharField(max_length=180)
description = models.TextField(blank=True)
Avant de pouvoir exploiter ce modèle, il nous faut prévenir Django de l'existence de notre application. Pour cela, on ajoute le nom de notre application dans la variable INSTALLED_APPS
du fichier demo_graphql/settings.py
.
INSTALLED_APPS = [
...
'interventions',
]
Nous pouvons désormais créer les tables dans la base de données
python manage.py makemigrations
python manage.py migrate
Avec GraphQL, un Type est un objet pouvant contenir plusieurs champs. Chaque champ est calculé via des résolveurs, qui renvoie une valeur. Une collection de types s'appelle un Schema. Chaque schema possède un type spécial appelé requête pour obtenir des données du serveur et une mutation pour envoyer des données au serveur.
Nous pouvons donc créer notre schema dans un fichier schema.py
situé dans à la racine de notre application:
import graphene
from graphene_django import DjangoObjectType
from .models import Intervention
class InterventionType(DjangoObjectType):
class Meta:
model = Intervention
class Query(graphene.ObjectType):
interventions = graphene.List(InterventionType)
def resolve_interventions(self, info, **kwargs):
return Intervention.objects.all()
Dans ce fichier, nous avons créé un nouveau Type avec un resolveur pour retourner les interventions.
Un nouveau fichier schema.py
situé à la racine de notre projet, hérite du schema de notre application des interventions et nous permet de cloisonner et maintenir nos développements.
import graphene
import interventions.schema
class Query(interventions.schema.Query, graphene.ObjectType):
pass
schema = graphene.Schema(query=Query)
Il nous reste une dernière étape avant de pouvoir requêter les données présentes en base, il s'agit de spécifier l'url sur laquelle GraphiQL est disponible.
GraphiQL est l'implémentation de référence de GraphQL IDE, un projet officiel de la Fondation GraphQL. C'est donc une interface qui nous permet de créer nos requêtes.
Pour cela, il convient de spécifier notre url dans le fichier urls.py
situé à la racine de notre projet:
from django.contrib import admin
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from graphene_django.views import GraphQLView
urlpatterns = [
path('admin/', admin.site.urls),
path('graphql/', csrf_exempt(GraphQLView.as_view(graphiql=True))),
Nous pouvons désormais nous rendre sur http://127.0.0.1:8000/graphql/ et effectuer nos premières requêtes.
Effectuer des requêtes avec GraphQL
Il est désormais très facile de remonter nos interventions. Dans le panneau de gauche, l'éditeur permet de sélectionner les objets que nous souhaitons récupérer.
Voici par exemple comment récupérer les identifiants de l'ensemble des interventions:
Bien entendu, nous pouvons aller plus loin et exploiter l'ensemble des données disponibles pour chaque interventions:
Voila, nous avons réalisé nos premières requêtes avec GraphQL ! Vous pouvez désormais ajouter, supprimer ou modifier des champs au modèle et les récupérer via GraphiQL.
Dans un prochain article, nous complexifierons nos modèles et découvrirons les mutations, utiles pour la création d'objets ainsi que les filtres pour nous permettre de récupérer des entrées spécifiques.