Comment obtenir des API GraphQL instantanées sur votre application Django existante

API GraphQL sur votre application Django existante

TL; DR

Voici les sujets que nous aborderons dans cet article si vous souhaitez naviguer:

Pourquoi GraphQL?

GraphQL est un langage de requête de données développé par Facebook. Il n'est lié à aucune base de données spécifique. Il permet au client d'interroger simultanément plusieurs bases de données en leur demandant ce dont ils ont besoin. Il renvoie la réponse dans le format demandé par le client.

Construire un serveur GraphQL

Quelles sont les différentes approches disponibles pour construire un serveur GraphQL? Nous verrons comment le moteur Hasura GraphQL constitue le moyen le plus simple d’obtenir une API GraphQL sur votre base de données existante.

Configurer le moteur GraphQL

Nous allons installer le moteur Hasura GraphQL. Nous exposerons ensuite les tables sur une API GraphQL.

Sécuriser le serveur GraphQL

Migration de la poignée

Alors, commençons!

Pourquoi GraphQL?

Dans une application Django typique, toute nouvelle configuration requise ou modification de schéma nécessite l'ajout ou la modification d'une vue existante. Cela peut avoir un impact énorme sur la productivité des développeurs. Cela nécessitera des mises à jour du code à tous les endroits où une API particulière est utilisée.

C'est ici que GraphQL est utile. GraphQL est un langage de requête pour les API. Il résume plusieurs sources de données. Cela permet aux développeurs d'applications de demander des données dans le format dont ils ont besoin. Cela ne nécessite aucune modification de l'API backend. Au lieu d'appeler des points de terminaison individuels pour obtenir des données, nous appelons un seul point de terminaison. Nous récupérons toutes les informations souhaitées, structurées exactement comme nous le souhaitons.

Cela peut donc vous faire réfléchir: comment puis-je obtenir une API GraphQL sur mon application Django existante?

Construire un serveur GraphQL

Pour construire un serveur GraphQL, il vous suffit de définir un schéma. Un schéma est un répertoire des types de données de votre application. Les fonctions de résolveur indiquent au serveur où et comment récupérer les données pour chaque type de données.

Les approches actuelles impliquent de l'écrire à partir de zéro (schéma, fonctions de résolution) à l'aide d'outils comme django-graphene.

Dans cet article, j'utiliserai le moteur Hasura GraphQL pour obtenir une API GraphQL sur mon application Django existante s'exécutant localement. Nous arriverons à une solution comme indiqué dans le schéma ci-dessous.

Architecture avant et après l'intégration au moteur Hasura GraphQL

Le moteur Hasura GraphQL (HGE) vous donne l’API GraphQL en temps réel instantanée en plus de votre Postgres existant. HGE fonctionne hors de la boîte avec votre existant:

  • Base de données Postgres - Se connecte à votre base de données existante et fournit une API GraphQL à votre base de données.
  • Système d'authentification - Connectez-vous à votre système d'authentification existant pour sécuriser l'API GraphQL.
  • Système de migration - Hasura GraphQL Engine n’interfère pas avec le système de migration Django existant. Le schéma peut être géré séparément par le biais de models.py et de la migration django jusqu'à ce que le schéma suivi par le moteur GraphQL ne soit pas modifié. Vous trouverez plus d'informations sur la manière dont le moteur Hasura GraphQL gère votre état de schéma ici.

En outre, il est livré avec une console astucieuse (similaire à l’administrateur Django) qui peut être utilisée pour le débogage des API GraphQL.

Installation

Le moteur Hasura GraphQL peut être installé sur Heroku en utilisant le bouton ci-dessous:

Cliquez sur ce bouton pour déployer le moteur GraphQL sur Heroku.

ou sur n'importe quelle machine pouvant exécuter Docker. Consultez la section de démarrage pour plus d'informations.

Installation à l'aide de docker et connexion à Postgres existant

Avant d'installer Hasura GraphQL Engine, je dois obtenir la chaîne de connexion Postgres permettant au moteur Hasura GraphQL de se connecter à la base de données. Je peux obtenir la chaîne de connexion Postgres à partir de settings.py de mon application.

BASES DE DONNÉES = {
    'défaut': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'MOT DE PASSE': 'SECUREPASSWORD',
        "HOST": "172.17.0.1",
        'PORT': '5432',
    }
}

L'URL de connexion à la base de données deviendra:

postgres: // postgres: [email protected]: 5432 / postgres

Une fois le moteur Hasura GraphQL démarré, visitez http: // localhost: 8080 pour ouvrir Hasura Console comme ci-dessous. La section Données affiche une liste des tables non suivies présentes dans la base de données, regroupées par schéma. Si vous vous demandez quelles sont les tables non suivies, consultez la documentation pour plus d'informations.

Console moteur Hasura GraphQLConsole Hasura | Explorateur de données

La capture d'écran ci-dessus répertorie les tables créées par l'application Django, telles que définies dans ce fichier models.py sous des tables non suivies. Cliquez sur le bouton Ajouter pour afficher la liste des tables suivies à gauche. Cela les expose à être interrogés via les API GraphQL:

Pour vérifier si tout fonctionne, essayons de récupérer tous les auteurs disponibles dans le tableau:

requete {
  medium_author {
    identifiant
    Nom
    intérêts
  }
}

La réponse du moteur GraphQL est la suivante:

{
  "Les données": {
    "medium_author": [
      {
        "nom": "Karthik",
        "id": 2,
        "intérêts": "Cricket, Musique, Code"
      },
      {
        "name": "Second Author",
        "id": 4,
        "intérêts": "Hockey"
      }
    ]
  }
}

Relation objet / tableau

Le moteur GraphQL analyse votre schéma et suggère des relations basées sur les clés étrangères définies entre les tables.

Relations de clé étrangère suggérées

Le moteur GraphQL suggère automatiquement deux relations pour chaque clé étrangère rencontrée.

  • Relation objet: relation 1: 1. Par exemple, un article aura un seul auteur.
  • Relation entre tableaux 1: plusieurs. Par exemple, un auteur peut écrire plusieurs articles.

Dans le schéma de blog, mediumArticlesByauthorId est une "relation de tableau". Elle est basée sur la clé étrangère medium_article :: author_id -> id dans le medium_article. mediumAuthorByAuthorId est une «relation d'objet» basée sur la même clé étrangère.

Lorsque nous suivons ces relations, le schéma GraphQL dérivé contient les noms de relation. Les tables et les relations peuvent être interrogées en une seule requête:

Requête GraphQL avec relation de tableauRequête GraphQL avec relation d'objet

Authentification

Par défaut, le moteur GraphQL est installé en mode développement. Toutes les tables / vues suivies par le moteur GraphQL peuvent être visualisées / mises à jour sans aucun contrôle. Ceci est dangereux et n'est pas recommandé pour un environnement de production.

Hasura vous permet de définir des contrôles d'accès granulaires pour chaque champ de votre schéma GraphQL, essentiellement chaque table ou vue de votre schéma Postgres. Ces règles de contrôle d'accès peuvent utiliser des variables dynamiques qui entrent dans chaque demande. Consultez la documentation pour plus d'informations.

Le moteur GraphQL peut être sécurisé pour y accéder directement en configurant une URL Webhook. Ceci sera appelé par le moteur GraphQL pour valider chaque demande à moins que la demande ne contienne une clé d'accès valide.

Architecture de la manière dont la demande / réponse se produit

Avant de sécuriser le point de terminaison GraphQL avec access-key et auth-hook (URL Webhook), ajoutons une simple règle de contrôle d'accès à l'aide de la console Hasura afin d'empêcher l'auteur de récupérer uniquement ses données et d'effectuer une requête à l'aide de l'explorateur GraphQL.

Voici à quoi ressemble la règle de contrôle d'accès pour la table medium_author pour role = user.

Ajouter un contrôle d'accès à la table des auteurs

Je n'ai créé que l'autorisation de sélection, mais vous pouvez configurer les quatre types d'opération (sélectionner, insérer, mettre à jour, supprimer). Consultez la documentation pour plus d'informations.

Interrogeons la table medium_author et voyons quelle est la réponse:

Ici, veuillez noter que x-hasura-user-id est défini sur «2» et x-hasura-role sur «user». Ce sont les données d'authentification qui seront transmises par auth-hook en mode production (le moteur GraphQL a démarré avec access-key et auth-hook).

API sécurisée GraphQL

Sécurisons le moteur GraphQL avec une clé d’accès. Configurons auth-hook avec le gestionnaire d'authentification, dans ce cas l'application Django. Le Webhook configuré sera appelé par le moteur GraphQL. Le Webhook renverra approprix-hasura-role et x-hasura-user-id.

Essayons de faire la requête à nouveau et voyons quelle est la réponse:

Le Webhook configuré est rejeté car la demande n'est pas authentifiée. Essayons de vous connecter en tant qu’utilisateur et de faire la demande avec le jeton d’authentification de l’utilisateur. Le système d'authentification Django résout les cookies. Il ajoute les informations de l'utilisateur dans le contexte de la demande, qui peut ensuite être utilisé par le gestionnaire de demandes.

Dans l'intérêt de ce blog, j'ai écrit un middleware d'authentification simple. Il analysera Authorization: Bearer et le résoudra en un utilisateur Django. L'utilisateur sera ajouté au contexte de la demande. Voici l'extrait de code de la même chose.

Se connecter avec un utilisateur avec id = 2Interrogation avec l'utilisateur connecté

L'utilisateur est authentifié par le Webhook. Le Webhook renvoie les rôles x-hasura-user-id et x-hasura-role correspondants. Le moteur GraphQL répond avec les résultats appropriés tels que configurés dans les règles d'accès.

Système de migration

Le moteur Hasura GraphQL est fourni avec un puissant outil de migration inspiré de Rails pour vous aider à garder une trace des modifications que vous apportez à votre schéma. Lorsque vous utilisez la console Hasura, l'interface de ligne de commande Hasura crache des fichiers de migration pour vous. Vous pouvez les mettre dans le contrôle de version et même les éditer.

Par défaut, la console Hasura est servie par le moteur GraphQL. Il peut être utilisé pour tester rapidement les fonctionnalités fournies par le moteur GraphQL. Toutefois, si vous construisez une application complexe ou ajoutez Hasura à l’application ou à la base de données existante, vous devez stocker la migration pour vous assurer que votre itération et votre CI / CD se déroulent sans heurts.

Installer

Installez hasura en exécutant la commande suivante sur votre terminal si vous utilisez un ordinateur Mac / Linux. Sinon, rendez-vous dans nos docs pour installer hasura sur différents environnements.

curl -L https://cli.hasura.io/install.sh | frapper

L'exécution de la commande suivante initialisera un répertoire avec des fichiers de configuration hasura configurés pour utiliser votre moteur GraphQL.

$ hasura init - répertoire blog-hasura-app --endpoint http: // localhost: 8080 --access-key = mysecretkey
hasura init

Remplacez la valeur de endpoint et access-key par les valeurs appropriées.

Désactiver la migration

Étant donné que Django prend en charge les migrations par défaut, vous pouvez désactiver la migration Hasura en tapant console hasura sur votre terminal. Pour ouvrir la console Hasura, accédez à Données -> Migrations (dans la barre de navigation de gauche) et désactivez Autoriser les modifications du schéma postgres.

Nous pouvons toujours stocker les métadonnées Hasura simplement pour nous assurer que l'application est toujours dans un état récupérable:

Avant de désactiver la migrationAprès avoir désactivé la migration

Exportation de métadonnées

Exportez les métadonnées Hasura et stockez-les dans le dossier de migration. Cela garantira que votre système est toujours récupérable de tout état indésirable.

exportation de métadonnées hasura

La commande ci-dessus exporte le fichier metadata.yaml et le stocke dans le dossier migrations.

Assurez-vous que les tables / vues sont créées / modifiées uniquement via le fichier Django models.py pour éviter les incohérences.

Si vous souhaitez utiliser le système de migration Hasura à la place, consultez la documentation pour plus d'informations.

Hasura vous donne des API GraphQL en temps réel instantanées sur n'importe quelle base de données Postgres sans avoir à écrire de code backend.

Pour ceux d'entre vous qui débutent dans le moteur Hasura GraphQL, c'est un bon point de départ.