# Syntaxe des opérations GraphQL

Nous avons déjà vu comment [construire à partir d'une opération une requête à l'API GraphQL](https://developers.mobilic.beta.gouv.fr/guides/effectuer-une-requete-a-lapi). Nous allons maintenant détailler l'écriture d'une opération.

{% hint style="info" %}
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](https://graphql.org/).
{% endhint %}

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.

{% hint style="info" %}
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.
{% endhint %}

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

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

## Type d'opération <a href="#type-doperation" id="type-doperation"></a>

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 <a href="#identifiant-de-loperation" id="identifiant-de-loperation"></a>

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 <a href="#variables-doperation" id="variables-doperation"></a>

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`.

{% hint style="info" %}
Une opération GraphQL peut très bien inclure des variables à plusieurs niveaux de "nesting".
{% endhint %}

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 :

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

{% hint style="info" %}
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 `$`
  {% endhint %}

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

```json
{
  "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 <a href="#schema-de-la-reponse" id="schema-de-la-reponse"></a>

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 :

```graphql
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](https://spec.graphql.org/June2018/#sec-Response-Format). 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 :

```json
{
  "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.
