Béjean Développement

Créer une requête GraphQL simple pour Magento 2

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 <nicolas@bejean.eu>
 * @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