Syntaxe des opérations GraphQL

Nous avons déjà vu comment construire à partir d'une opération une requête à l'API GraphQL. Nous allons maintenant détailler l'écriture d'une opération.

Cette page donne un aperçu très condensé du langage de requêtes GraphQL. Pour des informations plus détaillées vous pouvez consulter la documentation officielle.

Une opération est constituée des éléments suivants :

  1. le type de l'opération, toujours précisé en premier

  2. l'identifiant de l'opération, c'est-à-dire son chemin dans le graphe des opérations

  3. les variables d'opération et leurs valeurs

  4. le schéma de la réponse, qui permet de sélectionner le niveau d'informations retournées par l'API.

La distinction entre 2 et 4 n'existe pas vraiment dans GraphQL, une opération étant vue comme la sélection d'un certain champ dans le graphe entier des opérations.

Nous nous servirons de l'opération de logActivity pour illustrer chacun de ces constituants :

mutation {
    activities {
        logActivity(userId: 222408790, missionId: 500, type: "work", startTime: 1616281275) {
            id
        }
    }
}

Type d'opération

L'API Mobilic utilise deux types d'opération définis par le standard GraphQL :

  • query pour toutes les opérations de lecture qui ne modifient pas l'état du système

  • mutation pour toutes les opérations qui vont modifier l'état du système (création, édition, suppression)

L'opération de logActivity crée une nouvelle activité pour un utilisateur, elle est logiquement une mutation.

Identifiant de l'opération

L'opération de logactivity a été regroupée avec les autres opérations relatives aux activités. Son chemin complet dans les opérations de mutation est activities -> logActivity.

Variables d'opération

Elles sont précisées entre parenthèses à côté de l'opération concernée. Dans le cas de l'opération de logActivity il y a quatre variables, userId, missionId, startTime et type.

Une opération GraphQL peut très bien inclure des variables à plusieurs niveaux de "nesting".

La syntaxe GraphQL permet de définir les variables dans l'opération mais de préciser leurs valeurs en dehors. Par exemple l'opération de login peut s'écrire :

mutation($type: String!, $startTime: TimeStamp!, $missionId: Int!, $userId: Int) {
  activities {
    logActivity(type: $type, startTime: $startTime, missionId: $missionId, userId: $userId) {
      id
    }
  }
}

Il est important de noter que :

  • les variables sont déclarées juste après le type de l'opération.

  • une variable est toujours précédée d'un $

Le corps JSON de la requête HTTP doit alors contenir un champ variables qui définit pour chaque variable la valeur à injecter :

{
  "query": "mutation logActivity($type: String!, $startTime: TimeStamp!, $missionId: Int!, $userId: Int) {\n  activities {\n logActivity(\n type: $type\n startTime: $startTime\n missionId: $missionId\n userId: $userId\n ) {\n id}}\n}\n"
  "variables": { "type": "work", "startTime": 1616281275, "missionId": 500, "userId": 222408790}
}

Schéma de la réponse

C'est une fonctionnalité très puissante de GraphQL : la possibilité de personnaliser la réponse de l'API parmi le graphe des objets.

Par exemple pour l'opération de logActivity on peut ne demander en retour que l'identifiant de l'activité créée :

mutation {
    activities {
        logActivity(userId: 222408790, missionId: 500, type: "work", startTime: 1616281275) {
            id
        }
    }
}

Le corps de la réponse sera au format JSON, et suivra le schéma de la requête, comme défini dans les spécifications GraphQL. Dans l'exemple précédent le JSON de retour contiendra un champ data (toujours présent dans le cas d'une requête sans erreurs), contenant un champ auth qui contient lui-même un champ login et ainsi de suite :

{
  "data": {
    "activities": {
      "logActivity": {
        "id": 1608
      }
    }
  }
}

Ce fonctionnement prend tout son sens pour les objets complexes avec un fort niveau d'imbrication : par exemple une entreprise, auxquels sont rattachés des utilisateurs, qui effectuent des missions, qui elles-mêmes regroupent plusieurs activités. En fonction de ses besoins l'appelant est libre de récupérer un graphe d'objets plus ou moins profond.

Dernière mise à jour