Comment créer une requête simple GraphQL pour Magento 2 ?

Pour commencer, il faut savoir qu’il existe 2 types de requêtes :

  • Query
  • Mutation

Chacune de ces 2 requêtes ont un rôle particulier, les requêtes de type Query` permettent de récupérer de la donnée. Tandis que les requêtes de type `Mutation permettent de modifier de la donnée.

Objectif

L’objectif est de pouvoir mettre en place une requête simple de type Query.

Tutoriel

Création du module

La première étape consiste à créer votre module. Pour cela, il faut créer les principaux fichiers, à savoir :

├── etc
│   ├── module.xml
├── CHANGELOG.md
├── composer.json
├── README.md
└── registration.php

Dans le fichier etc/module.xml`, ajouter le module `Magento_GraphQl dans la séquence de chargement :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="NicolasBejean_BaseGraphQl" setup_version="1.0.0">
        <sequence>
            <module name="Magento_GraphQl"/>
        </sequence>
    </module>
</config>

Mise en place d’une requête de type Query

Création du fichier schema.graphqls

Pour créer une requête, il faut créer un premier fichier de déclaration schema.graphqls` dans le dossier `etc.

Créer le fichier et insérer le contenu :

type Query {
    JustOne (
        question: [String] @doc(description: "Question of the JusteOne")
    ): JustOne @resolver(class: "NicolasBejean\\BaseGraphQl\\Model\\Resolver\\JustOne") @doc(description: "The JustOne query returns answer about an question")
}

La requête que l’on créé se nomme JustOne`, avant de renvoyer une réponse de type `JustOne`, elle nécessite un paramètre `question` de type `String.

A la suite ajouter la définition du type de réponse JustOne :

type JustOne @doc(description: "Just one query information") {
    item: [Answer] @doc(description: "An array of one answer")
}

Le type de réponse va transmettre dans item` un objet de type `Answer.

Terminons la définition de la requête par la définition de l’objet Answer, ajouter le bloc ci-dessous à la fin du fichier :

type Answer @doc(description: "Answer defines all information") {
    question: String @doc(description: "Answer question")
    answer: String @doc(description: "Answer")
}

Ce bloc permet de lister les différentes variables que nous souhaitons proposer dans l’objet Answer.

Création du resolver PHP JustOne

Créer le fichier PHP JustOne.php` dans le répertoire `Model/Resolver :

├── Model
│   └── Resolver
│       └── JustOne.php

Lorsqu’une requête GraphQL sera transmise à votre boutique en ligne Magento 2. Elle sera traitée par cette classe PHP.

<?php
declare(strict_types=1);

namespace NicolasBejean\BaseGraphQl\Model\Resolver;

use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;

/**
 * Class JustOne
 *
 * Classe nécessaire pour la récupération d'une réponse en GraphQL
 *
 * @author   Nicolas Béjean <[email protected]>
 * @link     https://www.bejean.eu
 */
class JustOne implements ResolverInterface
{
    /**
     * @inheritdoc
     */
    public function resolve(
        Field $field,
        $context,
        ResolveInfo $info,
        array $value = null,
        array $args = null
    ) {
        if (!isset($args['question']) ||
            !is_array($args['question']) ||
            count($args['question']) === 0) {
            throw new GraphQlInputException(__('"Question" of JustOne should be specified'));
        }

        $data = [];

        foreach ($args['question'] as $question) {
            try {
                $data[$question] = array(
                    'question' => $question,
                    'answer' => 'This is my answer'
                );
            } catch (NoSuchEntityException $e) {
                $data[$question] = array(
                    new GraphQlNoSuchEntityException(__($e->getMessage()), $e)
                );
            }
        }

        return [
            'item' => $data
        ];
    }
}

La méthode resolve` permet de traiter les données envoyées par la requête. On les retrouve dans le tableau `$args.

La valeur transmise dans le paramètre question nous permettra de traiter la demande puis de transmettre une réponse.

Le tableau de réponse $data` doit obligatoirement comporter l'ensemble des variables possibles de l'objet de réponse `Answer` définit dans le fichier `schema.graphqls.

Création de la requête GraphQL et résultat

Pour tester mes scripts GraphQL, j’utilise Insomnia Core. Vous pouvez utiliser celui que vous souhaitez.

La requête doit être envoyée à votre boutique en ligne, pour moi, l’adresse est http://localhost/graphql.

Voici la requête nous permettons d’obtenir une réponse à notre question :

{
  JustOne(question: "Tell me your question!") {
    item {
      question
      answer
    }
  }
}

Le résultat est un objet JSON, on y retrouve la question que nous avons transmis car elle est définit dans l’objet GraphQL Answer`, traitée par la classe PHP `JustOne puis demandée dans la requête.
On obtient également une réponse à notre question.

{
  "data": {
    "JustOne": {
      "item": [
        {
          "question": "Tell me your question!",
          "answer": "This is my answer"
        }
      ]
    }
  }
}

Avant de lancer votre requête, il est nécessaire d’installer le module et de lancer la compilation : bin/magento setup:upgrade && bin/magento setup:di:compile.

Sources

Tutoriel publié le 23/08/2020.

Dernière modification: 23 août 2020

Auteur