Blog

🥊 Gato GraphQL vs WPGraphQL : le combat !

Leonardo Losoviz
Par Leonardo Losoviz ·

Mise à jour 01/05/2024 : Découvrez la comparaison Gato GraphQL vs WPGraphQL.

Messssssssssssdames et messieurs.

Annonce du prochain combat

Bienvenue au MGM Grand Garden Arena pour le combat du siècle ! Ce soir, nous faisons l'histoire. Deux jeunes combattants vont se faire face dans le ring, s'affrontant pour le prix pour lequel ils ont tant travaillé :

Devenir le champion du monde de « GraphQL dans WordPress » 🏆

À notre droite, nous avons le champion en titre. Bien qu'ayant seulement 4 ans, il est déjà plein d'expérience, ayant récemment atteint la version 1.0 et été publié dans le répertoire wp.org, et il est très populaire parmi la foule.

🥁 Donnons 🥁 le 🥁 bienvenue 🥁 àààà 🥁 ...... WPGraphQL !

Le champion en titre, WPGraphQL

À notre gauche, nous avons le challenger. Il n'est dans le monde que depuis 1 mois, mais il est très énergique et ambitieux, affichant sa force dès le premier jour. C'est lui qui a cherché la rencontre d'aujourd'hui. Ce soir est sa chance, et le monde est attentif.

🥁 Donnons 🥁 le 🥁 bienvenue 🥁 àààà 🥁 ...... Gato GraphQL !

Le challenger, Gato GraphQL

Ce soir, nos concurrents se retrouveront face à face pour la première fois, dans un combat de 12 rounds. Alors qu'ils prennent position au centre du ring, attendant la cloche d'ouverture, ils s'étudient mutuellement, essayant de trouver les points vulnérables de l'autre. Cependant, ils n'affichent que de la confiance.

Les 2 glorieux combattants s'étudient mutuellement

Qui prévaudra ? WPGraphQL maintiendra-t-il son avantage, basé sur le soutien de ses partisans ? Ou le nouveau venu Gato GraphQL convaincra-t-il une communauté insoupçonnée de la puissance de ses poings, laissant un sillage d'émerveillement qui convertit la foule à ses côtés ?

Ce soir, mesdames et messieurs, nous le saurons.

Faites vos paris. Et profitez du combat !


🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣


On m'a récemment demandé d'expliquer les différences entre mon plugin, Gato GraphQL, et WPGraphQL.

Les deux plugins sont des serveurs GraphQL pour WordPress, ils servent donc le même objectif. Cependant, sous le capot ils ont des caractéristiques différentes, ce qui peut rendre l'un meilleur que l'autre pour satisfaire un comportement requis.

Même si je suis biaisé en faveur de mon propre plugin, j'ai essayé de faire une comparaison équitable, basée sur des sujets que je considère importants à la fois pour GraphQL et pour WordPress. (Si les lecteurs souhaitaient une comparaison sur un autre sujet, je serai heureux de le faire.)

La comparaison n'est pas exhaustive. Par exemple, j'aimerais aussi faire quelques benchmarks, mesurant la vitesse de résolution de la même requête GraphQL avec les deux serveurs. (Si les lecteurs trouvent cette proposition intéressante, je peux le faire pour un prochain article.)

J'ai divisé ma comparaison en 4 domaines principaux : Popularité, Style de code et standards, Questions pressantes, et Élargir la portée, avec 3 éléments pour chacun, donnant un total de 12 « rounds ». À la fin, les juges rendent leur verdict, pour nommer le champion.

Cliquez ci-dessous pour accéder directement à un sujet :

🔔 Ding 🔔 ding 🔔 diiiiiing...

La cloche d'ouverture a sonné...

Le combat a commencé !


Popularité

Tout logiciel (ou technologie, d'ailleurs) doit être utilisé par des personnes, sinon le fait d'être meilleur que les alternatives ne sera qu'une anecdote.

Par exemple, même s'il existe des alternatives permettant de taper plus vite, nous utilisons encore principalement le clavier QWERTY.

Quelle est la popularité des deux plugins ?

Round 1 : Qui l'utilise, et quelle est son exhaustivité

WPGraphQL a été, jusqu'à présent, synonyme de GraphQL dans WordPress. Pendant les 4 ans et plus qu'il a été développé (à partir de novembre 2016), il a rassemblé plus de 2,8k étoiles sur le dépôt, une communauté de plus de 4600 abonnés, et presque 100 contributeurs au projet.

Il a atteint la version 1.0 et a été téléversé dans le répertoire de plugins sur wp.org en novembre 2020. Depuis lors, il a rassemblé plus de 8000 installations actives. Il est actuellement la seule solution pour sourcer du contenu WordPress vers Gatsby et, plus récemment, plusieurs projets l'ont ajouté à leurs stacks, dont le framework Headless de WPEngine et le starter WordPress Next.js de WebDevStudios.

En d'autres termes, WPGraphQL est populaire.

Le développement de Gato GraphQL a commencé sérieusement il y a environ 1,5 an (dans le cadre d'un projet plus large), et il a atteint un statut « suffisamment bon » il y a 6 mois, recevant 150 étoiles sur le dépôt depuis lors. Le plugin est actuellement à la version 0.7, et il lui reste encore plusieurs mois avant d'atteindre la 1.0 (par exemple, il n'a pas encore de catégories dans le schéma).

Le mois dernier, j'ai lancé ce site actuel gatographql.com, et depuis lors j'ai promu le plugin via le blog (comme l'article que vous lisez maintenant), et j'ai également publié un article d'introduction sur CSS-Tricks. Ces tentatives ont amené plusieurs centaines de personnes sur le site, et plus de 100 visiteurs ont téléchargé le plugin.

En d'autres termes, Gato GraphQL gagne lentement mais régulièrement en popularité, et c'est un travail en cours.

Vainqueur du round : WPGraphQL.

C'est un coup ! Le poing de WPGraphQL atteint Gato GraphQL

Round 2 : Disponibilité des extensions

Les extensions permettent d'interagir avec d'autres plugins via Gato GraphQL.

WPGraphQL dispose d'extensions pour ACF, WooCommerce, Yoast et quelques autres.

Gato GraphQL n'a pas encore d'extensions, et je ne m'attends pas à ce qu'il y en ait beaucoup avant la sortie de la version 1.0.

Cependant, Gato GraphQL met beaucoup l'accent sur les extensions dans son architecture, permettant à l'utilisateur de les gérer (activer, désactiver, configurer et lire leur documentation) depuis un endroit central, la page « Modules » :

Page Modules dans Gato GraphQL

En d'autres termes, alors que WPGraphQL a déjà des extensions, Gato GraphQL prépare le terrain pour elles.

Vainqueur du round : WPGraphQL.

WPGraphQL frappe à nouveau !

Round 3 : Public cible

WPGraphQL cible les développeurs : si vous voulez extraire des données de votre site WordPress, vous devez stocker votre requête GraphQL quelque part dans votre code (très probablement, dans une fonction JavaScript). Ensuite, pour pouvoir l'utiliser, vous devez être suffisamment doué en programmation.

Gato GraphQL, en revanche, suit la philosophie WordPress selon laquelle n'importe qui devrait pouvoir l'utiliser, y compris les non-techniciens. Pour atteindre cet objectif, il permet de créer et gérer une requête GraphQL via l'éditeur WordPress, de sorte que rendre les données du site WordPress accessibles via une API devienne aussi facile que créer un article de blog.

De plus, Gato GraphQL met davantage l'accent sur l'offre de clients pour interagir avec le service GraphQL de manière visuelle. Alors que les deux plugins fournissent le client GraphiQL, pour exécuter la requête, seul Gato GraphQL fournit également le client Voyager, pour explorer interactivement le schéma :

Visualisation du schéma GraphQL

Vainqueur du round : Gato GraphQL.

Gato GraphQL assène un bon coup gauche !


Style de code et standards

Parlons code !

Si vous utilisez GraphQL, il y a de bonnes chances que vous fassiez du WordPress headless et que vous rendiez le site web en utilisant un framework JavaScript, ce qui est un paradigme moderne. De plus, WordPress est peut-être un vieux CMS, mais GraphQL est une interface moderne pour accéder aux données du site. Ainsi, je peux supposer sans risque que vous êtes un développeur avisé, désireux de produire du code élégant, et que vous n'accepterez pas d'utiliser une solution sous-optimale.

Quel est le degré d'élégance du code (de leur propre base de code, et attendu de nos implémentations personnalisées) de ces deux plugins ?

Round 4 : Exigences PHP

WPGraphQL et Gato GraphQL requièrent tous deux PHP 7.1+.

Cependant, il y a une différence : Gato GraphQL est en fait codé en utilisant PHP 7.4, et est ensuite transpilé vers PHP 7.1 pour la production.

Ainsi, coder Gato GraphQL est beaucoup plus agréable : vous pouvez utiliser des fonctionnalités PHP plus récentes, notamment le type object, les propriétés typées et les arrow functions. Et une fois le support de PHP 8.0 ajouté (ce qui se produira lorsque la nouvelle version de Lando sera publiée), vous pourrez également utiliser les union types, l'expression match, et d'autres.

Vainqueur du round : Gato GraphQL.

Gato GraphQL laisse sa marque !

Round 5 : Pratiques de codage

Commençons par WPGraphQL. En allant sur le dépôt wp-graphql/wp-graphql, il y a quelque chose qui me frappe :

Le dossier vendor stocké dans le dépôt

En zoomant :

Contenu du dossier vendor

Désolé, mais il n'y a qu'une seule façon pour moi de réagir à ça :

Je peux vous pardonner beaucoup de choses dans la vie, mais pas ça

Committer le dossier vendor de Composer dans le dépôt est une mauvaise pratique, et Composer le déconseille explicitement.

Corriger ce problème n'est pas difficile (j'ai même décrit une façon basée sur les GitHub actions), donc je me demande pourquoi c'est là.

Je dirais que, dans ce round, WPGraphQL se frappe lui-même !

Aïe !

Continuons. Développer pour WPGraphQL nécessite de connaître une collection super étendue de hooks (actions et filtres). En allant dans la référence développeur de WPGraphQL, on peut apprécier l'étendue de cela.

Pour prendre une capture d'écran de la liste des actions, j'ai dû dézoomer mon navigateur à 50 % :

Action hooks pour étendre WPGraphQL

Pour la liste des filtres, j'ai dézoomé à 30 % (le minimum que Firefox supporte), et même ainsi je n'ai pas pu obtenir la liste complète :

Filter hooks pour étendre WPGraphQL


Passons au dépôt GatoGraphQL/GatoGraphQL, qui est le monorepo contenant Gato GraphQL (entre autres projets).

Voici quelques-unes des caractéristiques du code :

✅ Conforme aux standards PSR-1, PSR-4 et PSR-12.

✅ Tout le code est divisé en plusieurs packages atomiques, et tous (plus de 100 pour le plugin, plus de 200 pour l'ensemble du projet) sont hébergés dans le même monorepo.

✅ Utilise Composer pour gérer toutes les dépendances.

✅ Utilise Symfony Dependency Injection pour gérer tous les services de l'application. Pour enregistrer un nouveau type resolver, field resolver ou directive resolver, nous devons simplement enregistrer un nouveau service dans le conteneur.

✅ Chaque classe est un service, et Symfony Dependency Injection se charge d'assembler automatiquement toute l'application.

✅ Le serveur GraphQL sous-jacent est CMS-agnostic. Gato GraphQL implémente les contrats pour WordPress, et ajoute un peu de logique personnalisée (par exemple, pour fournir les clients).

Le code spécifique à WordPress représente seulement environ 10 % du code global. Répliquer ce 10 % pour un autre framework ou CMS (Laravel/Drupal/etc) peut fournir une implémentation d'un serveur GraphQL pour eux également.

✅ En conséquence d'être CMS-agnostic, coder un resolver implique de coder sa logique métier générique, alimentée par des services réutilisables. Nous ne pensons jamais en termes de code WordPress, et nous devons rarement gérer sa dette technique.

✅ De même, le schéma GraphQL n'est pas une réplique 1:1 du modèle de données WordPress, contournant la dette technique accumulée par WordPress au niveau de la couche de données, et fournissant une interface propre.

✅ Le problème N+1 de GraphQL ne peut pas se produire, par conception architecturale, et sans perturber le développeur.

✅ Le serveur n'est pas seulement un serveur GraphQL : c'est en fait un serveur API, où la réponse peut être émise dans d'autres formats ou spécifications (ex : REST) à partir d'une seule source de vérité. (Plus à ce sujet au round 11).

✅ Aucun répertoire vendor n'est commité. À la place, le code source est transformé en code de distribution (c'est-à-dire le plugin final à installer sur le site WordPress) via GitHub actions, et déployé vers un dépôt dist, où il contient bien le dossier vendor.

✅ Lors de la génération du code pour la distribution, il est scopé avec PHP-Scoper, et le code source, qui contient du code PHP 7.4, est transpilé vers PHP 7.1.

✅ Parce qu'il a résolu le scoping, le plugin peut s'appuyer sur n'importe quelle dépendance tierce. Actuellement, il utilise DependencyInjection de Symfony, Cache et Dotenv, Guzzle (pour interagir avec des APIs externes), le Pipeline de la League, et plusieurs autres.

C'est important non seulement pour le présent, mais aussi pour l'avenir : je peux avoir la certitude que je peux utiliser n'importe quelle dépendance du dépôt Packagist, donc je n'ai pas besoin de réinventer la roue.

Les champs sont abonnés aux types, rendant le schéma GraphQL facile à étendre.

Vainqueur du round : Gato GraphQL (de loin, j'ose le dire, si vous permettez).

Après un round difficile, WPGraphQL a besoin d'un peu de repos

Round 6 : Étendre le schéma

Ajoutons un champ au schéma GraphQL.

Nous suivons le tutoriel pour WPGraphQL. Le code suggéré est celui ci-dessous. Il déclare un action hook pour exécuter une fonction qui déclare un tableau. La description des champs et leur résolution sont fournies dans le tableau :

add_action( 'graphql_register_types', function() {
 
	register_graphql_field( 'RootQuery', 'myNewField', [
		'type' => 'String',
		'args' => [
			'myArg' => [
				'type' => 'String',
        'description' => __( 'Description for how the argument will impact the field resolver', 'your-textdomain' ),
			],
		],
		'resolve' => function( $source, $args, $context, $info ) {
			if ( isset( $args['myArg'] ) ) {
				return 'The value of myArg is: ' . $args['myArg'];
			}
			return 'test';
		},
	]);
 
});

Cet exemple est aussi simple que possible : le resolver ne fait pratiquement rien. Pourtant, j'ai déjà du mal à regarder le code et à comprendre immédiatement ce qu'il fait. Non, je ne suis pas sarcastique : toutes les couleurs de ce code dans mon éditeur se disputent mon attention. De plus, il n'y a pas de séparation des préoccupations, et le code ne semble pas très réutilisable.

Ainsi, il incombera au développeur (c'est-à-dire à vous) de rendre le code facile à lire, réutilisable, sans bugs, et bien d'autres choses, tout en développant l'application ; la bibliothèque elle-même ne semble pas beaucoup aider à cet égard.

J'appelle ce style « ADD » : Array-Driven Development. Je ne peux pas dire que j'en suis fan.

(Pour être équitable envers WPGraphQL, c'est une pratique de codage standard, et c'est aussi celle employée par le moteur sous-jacent webonyx/graphql-php.)


Dans Gato GraphQL, tout le code est SOLID. Pour enregistrer un champ dans le schéma GraphQL, nous créons une classe implémentant l'interface FieldResolverInterface (en réalité, en étendant AbstractSchemaFieldResolver, qui a de nombreuses méthodes déjà implémentées), et nous la registrons dans le conteneur.

Par exemple, ce code fournit les champs username, email et url au type User :

class UserFieldResolver extends AbstractSchemaFieldResolver
{
  public static function getClassesToAttachTo(): array
  {
    return [
      UserTypeResolver::class,
    ];
  }
 
  public static function getFieldNamesToResolve(): array
  {
    return [
      'username',
      'email',
      'url',
    ];
  }
 
  public function getSchemaFieldDescription(TypeResolverInterface $typeResolver, string $fieldName): ?string
  {
    $descriptions = [
      'username' => $this->translationAPI->__("User's username handle", "users"),
      'email' => $this->translationAPI->__("User's email", "users"),
      'url' => $this->translationAPI->__("URL of the user's profile in the website", "users"),
    ];
    return $descriptions[$fieldName];
  }
 
  public function getSchemaFieldType(TypeResolverInterface $typeResolver, string $fieldName): ?string
  {
    $types = [
      'username' => SchemaDefinition::TYPE_STRING,
      'email' => SchemaDefinition::TYPE_EMAIL,
      'url' => SchemaDefinition::TYPE_URL,
    ];
    return $types[$fieldName];
  }
 
  public function resolveValue(TypeResolverInterface $typeResolver, object $user, string $fieldName, array $fieldArgs = [])
  {
    switch ($fieldName) {
      case 'username':
        return $this->usersAPI->getUserLogin($user);
 
      case 'email':
        return $this->usersAPI->getUserEmail($user);
 
      case 'url':
        return $this->usersAPI->getUserURL($user);
    }
 
    return null;
  }
}

Je crois que ma solution est plus élégante que celle de WPGraphQL. Cependant, c'est une question de goût. Je sais que de nombreux développeurs ne sont pas dérangés par l'Array-Driven Development, et le préfèrent même car, dans un bloc de code compact, ils peuvent implémenter toute la logique.

Vainqueur du round : match nul.

Match nul


Entracte

Quelle nuit nous avons, mesdames et messieurs.

Moment d'analyser le combat jusqu'ici

Nous avons atteint le milieu du combat, c'est donc le bon moment pour une pause toilettes, et pour commenter ce que nous avons vécu jusqu'à présent.

(Entre-temps, je devrais afficher une publicité de mes sponsors. Malheureusement, je n'en ai pas encore. Si vous souhaitez que votre entreprise finance le développement de Gato GraphQL, et obtienne une visibilité dans des médias de premier plan comme cet événement, envoyez-moi un message.)

Sponsorisez-moi, pour accéder à une publicité de premier plan pour votre marque

Quel combat nous avons ! WPGraphQL était initialement tout feu tout flamme ! Il a commencé le combat en grande forme, portant des coups terriblement puissants à Gato GraphQL, qui pouvait à peine se tenir sur ses deux pieds. Coup après coup après coup. Je ne voulais pas être à la place de Gato GraphQL.

Je dois admettre, j'ai pensé qu'après les 2 premiers rounds, le combat serait bientôt terminé. Je m'attendais au knock-down à tout moment. À voir une serviette ondulante demandant grâce. Mais Gato GraphQL a résisté. Il faut lui reconnaître ça. Quelle détermination inébranlable, c'est vraiment remarquable !

Et puis, la transformation s'est produite. À partir du 3ème round, Gato GraphQL semblait puiser de l'énergie de nulle part, et a commencé non seulement à se défendre, mais à lancer des coups en retour, dont beaucoup ont atteint le visage de WPGraphQL. J'ai vu WPGraphQL trembler et vaciller ! Nous n'avions jamais rien vu de tel de notre champion du monde actuel. Quelle transformation vraiment remarquable nous venons de vivre !

Et alors, ayant la confiance de son adversaire ébranlée, à partir du 4ème round Gato GraphQL a pris sur lui de porter une série de coups létaux. C'était saisissant ! Heureusement, face à lui se trouve notre champion du monde, WPGraphQL, et il a pu encaisser les coups, porté par les acclamations et la compassion de la foule. Quel héros il est ! N'importe qui d'autre aurait succombé sur le coup, mais pas lui, il a enduré les coups comme le champion qu'il est.

Mais champion, le sera-t-il encore longtemps ? Personne n'a encore été mis KO, personne n'a encore jeté l'éponge. Le combat pourrait à tout moment prendre un tournant décisif. Les deux combattants savent ce qu'ils veulent, et je suis sûr qu'ils reviendront avec toute leur puissance, et toute leur détermination, pour s'en prendre à leur adversaire, pour prévaloir.

Quel combat nous avons !

Et maintenant, mesdames et messieurs, les deux guerriers reviennent dans le ring.

Les concurrents reviennent dans le ring

Place au reste du combat !


Questions pressantes

Le serveur GraphQL doit prêter attention à de nombreuses considérations, juste pour satisfaire la proposition « récupérer les données dont vous avez besoin, ni plus ni moins ».

Par exemple :

  • À quel point est-il sécurisé ? Comment s'assurer que nous n'exposons pas de données privées sur un endpoint public ?
  • À quel point est-il performant ? Comment pouvons-nous réduire la charge sur le serveur lors de l'envoi répété de la même requête, tout en le rendant aussi rapide que possible ?
  • À quel point est-il simple ? Quelle est son intégration avec WordPress, de manière à exploiter les fonctionnalités fournies par le CMS ?

Et bien d'autres questions. C'est juste un petit échantillon que j'ai choisi, et que je vais traiter dans les 3 rounds suivants.

Round 7 : Persisted queries

Les persisted queries combinent le meilleur de GraphQL et de REST : elles sont créées en utilisant GraphQL, donc il n'y a pas de sous/sur-récupération de données, mais elles sont publiées sur le serveur comme un endpoint, avec sa propre URL.

Les persisted queries offrent ces avantages :

✅ C'est sécurisé : au lieu de donner accès à n'importe quelle donnée via le seul endpoint, nous pouvons prédéfinir quelles données exposer.

✅ C'est rapide : étant accessible via sa propre URL, elle peut être mise en cache sur chaque couche entre le client et les back-ends (dans le serveur, CDN, navigateur) en utilisant le HTTP caching standard.

WPGraphQL offre la prise en charge des persisted queries via ces deux extensions :

De plus, Jason Bahl (créateur de WPGraphQL) a récemment annoncé que dans un futur proche il ajoutera le support des persisted queries dans WPGraphQL.

Je me demande ce qu'il a en tête, car il y a déjà 2 extensions. En quoi sera-t-il différent de celles-là ? Peut-être veut-il en faire une partie du core du plugin, pour renforcer les mesures de sécurité globales du plugin sans dépendre d'un tiers ?

Ou peut-être a-t-il vu l'implémentation de Gato GraphQL, et veut-il fournir une expérience similaire, en l'opérant via un éditeur visuel plutôt que du code pur ?

Ce qui nous amène à Gato GraphQL. Non seulement il offre des persisted queries, mais il s'est efforcé d'en faire un élément central de l'offre :

✅ Le plugin permet de désactiver le seul endpoint, et les utilisateurs sont encouragés à exposer les données uniquement via des persisted queries.

(En revanche, WPGraphQL ne fait que désactiver l'introspection par défaut, pas l'endpoint lui-même. En d'autres termes, les attaquants peuvent toujours être en mesure d'accéder aux données privées ; on leur rend juste la tâche plus difficile, puisqu'ils ne sauront pas à l'avance quelles données privées il y a.)

✅ Il est profondément intégré avec l'éditeur WordPress, de sorte que créer une persisted query demande le même effort que créer un article de blog, et n'importe qui peut le faire, pas seulement les programmeurs.

✅ Les persisted queries ne sont pas statiques : elles peuvent utiliser des variables GraphQL, dont la valeur peut être fournie via des paramètres URL lors de l'exécution de l'endpoint.

Consultez l'expérience de création et d'exécution d'une persisted query dans mon plugin :

Vainqueur du round : Gato GraphQL.

Round 8 : Mise en cache

GraphQL a un gros point faible : il n'est pas facilement mis en cache. La raison est qu'il dépend de l'envoi d'opérations POST à un seul endpoint. Comme le seul endpoint produira des résultats différents, et comme la requête est envoyée dans le corps de la demande plutôt que dans les paramètres URL, nous ne pouvons pas avoir le seul endpoint mis en cache.

La solution standard offerte par de nombreux serveurs GraphQL est de déplacer la mise en cache vers le client, et de s'appuyer sur les IDs des objets comme identifiants de l'entité à mettre en cache plutôt que sur l'URL d'un endpoint. La bibliothèque la plus populaire fournissant cette fonctionnalité est le client Apollo.

Il y a une discussion sur le dépôt WPGraphQL sur toutes les options disponibles pour la mise en cache de WPGraphQL. Fait intéressant, la plupart d'entre elles sont des outils externes (comme le client Apollo, ou le WordPress Object Cache), ce qui signifie ajouter une couche supplémentaire à l'application, augmentant sa complexité, et la ralentissant potentiellement aussi.

(Ces raisons doivent être en partie derrière la décision d'implémenter nativement les persisted queries dans WPGraphQL.)

Par exemple, le client Apollo s'exécute, eh bien, côté client. Si vous accédez au site web depuis un téléphone mobile bas de gamme, sans beaucoup de puissance, ce code JavaScript supplémentaire aura un impact sur les performances de l'application.

De même, les développeurs travaillant avec WordPress peuvent être compétents en PHP, mais pas tellement en JavaScript. Maintenant, mettre leurs APIs en cache signifiera qu'ils devront aussi se soucier de la couche JavaScript.

Gato GraphQL a été plus intelligent sur ce sujet. Puisqu'il fournit des persisted queries, ce qui signifie que les requêtes sont exécutées sur leur propre endpoint, il permet de mettre en cache ces URLs d'endpoint via le HTTP caching.

L'en-tête HTTP caching a la valeur max-age calculée automatiquement à partir de toutes les valeurs max-age pour tous les champs de la requête, et cette information est configurée en utilisant l'éditeur WordPress, champ par champ.

En conséquence, l'API peut être mise en cache sur plusieurs couches (dans le client, CDN et serveur), et elle est gérée nativement dans le plugin, sans avoir besoin d'ajouter une autre couche.

Consultez cette vidéo montrant comment les endpoints API sont mis en cache :

Vainqueur du round : Gato GraphQL.

Round 9 : Intégration avec Gutenberg

Gutenberg était autrefois le futur de WordPress. Ce n'est plus le cas : Gutenberg est maintenant le présent de WordPress (nous pouvons donc y faire référence comme l'éditeur WordPress), et Full Site Editing est devenu le nouveau futur.

Inutile de dire que nos APIs doivent avoir une bonne intégration avec l'éditeur WordPress. Cela signifie non seulement pour récupérer et publier des données pour les blocs, mais aussi pour potentiellement alimenter des fonctionnalités dans l'éditeur WordPress lui-même.

Par exemple, comme les subscriptions GraphQL peuvent faire envoyer des données par le serveur au client en temps réel, elles seraient adaptées pour alimenter les fonctionnalités d'édition collaborative et de notifications.

WPGraphQL peut interroger des données de blocs via l'extension WPGraphQL Gutenberg. Cette extension crée un nouveau type pour mapper chaque bloc, donc nous avons CoreParagraphBlock, CoreQuoteBlock, etc.

Gato GraphQL pourra bientôt interroger des données de blocs (c'est un travail en cours). Cependant, au lieu de créer un nouveau type par bloc, il aura un seul type Block pour représenter tous les blocs, et nous pourrons ensuite extraire les métadonnées spécifiques pour un bloc en fonction de son nom.

Par exemple, regardez comment vous pouvez traduire le contenu à l'intérieur d'un bloc paragraphe (en utilisant la directive @strTranslate, qui se connecte à l'API Google Translate) :

query TranslateStringsInBlocks {
  post(by: { id: 1657 }) {
    title
    paragraphBlocks: blockDataItems(
      filterBy: { include: "core/paragraph" }
    )
    translatedParagraphBlocks: blockDataItems(
      filterBy: { include: "core/paragraph" }
    )
      @underJSONObjectProperty(by: { path: "attributes.content" })
        @underEachArrayItem
          @strTranslate(from: "en", to: "fr")
  }
}

Vainqueur du round : match nul.


Élargir la portée

« J'ai un rêve. »

Les blocs Gutenberg ont été conçus pour fournir une interface unique pour créer du contenu dans WordPress, simplifiant grandement le développement du code pour le CMS, et l'apprentissage requis des utilisateurs.

Bien qu'introduits pour créer du contenu, les blocs prennent progressivement le contrôle de tous les autres domaines du CMS, y compris les widgets, les menus et, bientôt, les thèmes via Full Site Editing. Et à l'avenir, ils supporteront également les capacités multilingues et l'édition collaborative (des fonctionnalités auxquelles nous pourrions même ne pas penser en pensant aux blocs), et qui sait quoi d'autre.

Nous pouvons penser à GraphQL dans les mêmes termes : comme une interface unique pour interagir avec les données. Cela signifie, non seulement récupérer et publier des données, mais toute interaction impliquant des données, y compris l'édition.

WordPress a une chance unique de vraiment devenir le système d'exploitation du web : un système alimenté par Gutenberg, qui permet à l'utilisateur de saisir n'importe quel type de contenu (texte, images, vidéo, audio, etc), de le traiter via ses propres outils ou un service basé sur le cloud, et de le publier vers sa destination finale, que ce soit le site WordPress ou ailleurs.

Mais derrière ce puissant rêve, il doit y avoir une API vraiment puissante, pour répondre à toutes les exigences que nous lui imposons. Une API qui pourrait être basée sur GraphQL, mais qui a été conçue pour également transcender ses limitations.

Round 10 : Support des directives personnalisées

Début du round 10

WPGraphQL ne vient avec pas une seule directive. Je ne dis pas qu'il ne les supporte pas (son moteur webonyx/graphql-php le fait), mais qu'il n'offre pas d'implémentation de directive personnalisée.

« Et alors ? » pourriez-vous penser. « Pourquoi avons-nous besoin de directives ? Si quelqu'un a besoin de modifier le résultat de la requête, il peut le faire sur son propre client ! »

Pourquoi ai-je besoin de directives ?

C'est une question d'opinion, et il n'y a pas de bonne ou de mauvaise réponse. Mais laissez-moi vous dire quelque chose : les directives sont une fonctionnalité incroyablement utile, qui aide à distinguer GraphQL de REST. Si vous ne les utilisez pas, vous ne tirez probablement pas le meilleur parti de votre API.

Les directives sont non réglementées par la spec, donc les serveurs GraphQL peuvent les implémenter comme ils le souhaitent, les rendre aussi puissantes qu'ils en ont besoin. C'est pourquoi de nombreuses nouvelles fonctionnalités de GraphQL sont d'abord introduites via des directives, comme @stream et @defer.

Gato GraphQL traite les directives avec révérence. Elles sont exécutées une seule fois avec les données de toutes les entités, pour tous les champs auxquels elles sont appliquées (ce qui explique pourquoi la directive @strTranslate peut récupérer des résultats de l'API Google Translate si rapidement), et le moteur GraphQL lui-même est basé sur un pipeline de directives.

Ahhhh, mais vous avez peur de rendre toute cette puissance disponible aux utilisateurs, n'est-ce pas ? C'est une préoccupation valide. Mais alors, vous pouvez simplement supprimer l'accès au seul endpoint, et fournir l'accès aux données uniquement via des persisted queries, où vous (l'administrateur du site) êtes la seule personne ayant accès aux directives.

Donc soit vous en bénéficiez, soit rien ne se passe.

Si vous aimez les directives, super, vous allez adorer Gato GraphQL ! ❤️

Mais, d'un autre côté, si vous n'aimez pas ça, rien ne se passe.

Vainqueur du round : Gato GraphQL.

(Si vous croyez que « nous n'avons pas besoin de ces sales directives », veuillez ne pas m'en vouloir... Je fais juste mon travail.)

Round 11 : Support de REST

« Ahhhhh ? REST ? Quel REST ? Ne parle-t-on pas de GraphQL ici ? Pourquoi parlez-vous de REST alors ? Pourquoi voulez-vous compliquer ma vie ? »

Plus que ça, je ne peux pas faire pour vous

Oui, à première vue ce sujet semble déplacé. Mais je l'ai ajouté dans cette comparaison pour une raison très simple : Matt Mullenweg a dit qu'il étudie GraphQL pour une inclusion potentielle dans le core de WordPress, et la seule chose dont les contributeurs s'inquièteront est d'avoir à maintenir deux bases de code.

Ce qui mène à la question évidente : le serveur GraphQL peut-il également gérer REST ?

La réponse est « partiellement oui » pour WPGraphQL, et « complètement oui » pour Gato GraphQL.

Concernant WPGraphQL. Il est possible de définir un endpoint REST qui, lors de sa résolution, exécute simplement une requête GraphQL contenant les champs requis, soit comme un appel interne au moteur GraphQL, soit comme une opération POST externe exécutée contre le même serveur web.

Mais ce n'est pas suffisant pour satisfaire la WP REST API, car elle a aussi un schéma JSON, et nous ne pouvons pas s'en passer.

Concernant Gato GraphQL. Je dois admettre que j'ai eu de la chance, car le travail sur son moteur sous-jacent (le modèle de composants côté serveur appelé PoP) a commencé vers 2013, c'est-à-dire plusieurs années avant que je connaisse quelque chose appelé GraphQL, et ce projet a évolué avec des idées propres (que j'ai documentées dans cet article vintage).

Ensuite, quand j'ai commencé à coder le serveur GraphQL CMS-agnostic (sur lequel repose Gato GraphQL) il y a environ 1,5 an, j'ai fusionné les idées développées pour PoP, avec les fondements établis par GraphQL, créant un système qui supporte entièrement la spec GraphQL, tout en étant capable d'y ajouter un ensemble différent de fonctionnalités.

À cet égard, le schéma que PoP utilise est API-agnostic, et c'est un sur-ensemble de celui de GraphQL. Le schéma PoP se trouve sous /api/graphql/?query=fullSchema.

Ensuite, la couche du serveur GraphQL formate le schéma PoP en suivant la spécification GraphQL, ce qui produit le schéma GraphQL. Et de la même façon, nous pouvons produire le schéma JSON requis par la WP REST API.

Générer ce schéma JSON n'a pas encore été fait, mais c'est faisable.

Ce qui a déjà été fait, c'est de produire la réponse de la requête dans plusieurs formats. Par exemple, cette requête GraphQL :

{
  posts {
    id
    title
    date
    author {
      name
    }
  }
}

Elle est aussi résolue via cet endpoint REST : /posts/api/rest/?query=id|title|date|author.name.

Et nous n'avons pas besoin de nous arrêter là. Avez-vous besoin de produire les résultats dans un format encore différent, comme XML ? No problemo : /api/?query=posts.id|title|date|author.name&datastructure=xml.

(Cela pourrait aider à implémenter la proposition d'un nouvel outil d'import/export pour WordPress, basé sur un schéma. Cela rend aussi un peu plus évident ce que j'ai dit plus tôt : une seule interface peut alimenter toutes les interactions de données, à la fois dans le CMS, et aussi depuis le CMS avec des APIs externes.)

Vainqueur du round : Gato GraphQL.

Round 12 : Support des fonctionnalités nouvelles

La spec GraphQL est-elle définitive ? La réponse est non : la spec évolue constamment. En ce moment, il y a 100 problèmes ouverts, dont beaucoup contiennent des propositions qui seront formalisées à un moment dans le futur.

Parmi ces 100 problèmes, il y aura certainement de nouvelles fonctionnalités dont nous pouvons bénéficier aujourd'hui, n'est-ce pas ? Si oui, pourquoi attendre ?

C'est exactement ma façon de penser.

Nous ne pouvons pas attendre éternellement

« Mais si quelque chose n'est pas dans la spec GraphQL, alors nous ne devons pas l'ajouter au serveur GraphQL, ou les utilisateurs seront confus ! »

Bon point. Cependant, si nous rendons les nouvelles fonctionnalités disponibles uniquement en opt-in, alors les utilisateurs en seront nécessairement conscients, et aucun problème ou malentendu ne se produira.

Encore une fois, c'est ma façon de penser. C'est une question d'opinion cependant, donc si vous préférez n'utiliser que des fonctionnalités que chaque serveur GraphQL utilise également, c'est OK.

Je crois que c'est ainsi que WPGraphQL fonctionne. Du moins, je n'ai pas vu une seule fonctionnalité qui aille au-delà de ce qui a été approuvé dans la spec.

Pour Gato GraphQL, cependant, je scanne régulièrement la liste des problèmes dans la spec et, si je trouve une fonctionnalité intéressante, qui peut être satisfaite par mon serveur sans beaucoup d'effort, alors je l'implémente. (En fait, c'est l'un de mes passe-temps.)

Voici les fonctionnalités « tournées vers l'avenir » que j'ai implémentées à ce jour :

Exécution de multiples requêtes
Nommage de schéma
Mutations imbriquées
Directives composables
Retours proactifs
Versionnage basé sur les champs et les directives

Et je prévois déjà d'ajouter :

✳️ Subscriptions (cela fait déjà partie de la spec)
✳️ Directives @stream et @defer
✳️ Syntaxe de chaîne plate

Vainqueur du round : Gato GraphQL.


Verdict !

Mesdames, messieurs.

C'est le moment du verdict

Quelle nuit inoubliable nous avons vécue ! Quel combat nous venons de vivre ! Deux poids lourds donnant le meilleur d'eux-mêmes pour leur rêve.

Un rêve que tous deux poursuivent, mais qu'un seul peut atteindre.

Et maintenant, nous saurons qui c'est. Maintenant, c'est le moment de la vérité !

Qui sera le champion du monde de « GraphQL dans WordPress » ?

Sera-ce le champion actuel très acclamé, aimé des masses, présenté dans les grandes publications, WPGraphQL ?

Ou sera-ce l'irrévérencieux, qui écrase vos orteils sans demander pardon, arrive sans invitation à la fête, le challenger Gato GraphQL ?

Les concurrents attendent le verdict

Nous attendons le verdict du juge. Quelle tension ! Ô Sainte Marie, fais résister mon cœur à ce moment !

🥁 Et 🥁 le 🥁 vainqueur 🥁 essssssssssssst 🥁 ...

C'est un match nul !

Les 2 combattants, les 2 poids lourds, font match nul !

Les concurrents se serrent dans les bras

Quel merveilleux moment ! Les deux concurrents se serrent dans les bras, montrant que nous sommes tous amis au sein de la communauté WordPress, comme une grande famille que nous sommes.

Alors, quelle est la justification du match nul ? Le juge explique :

👑 WPGraphQL est le plus populaire, et son utilisation est plus répandue.

👑 Gato GraphQL a une meilleure architecture, et pourrait potentiellement mieux servir WordPress sur le long terme.

Mesdames et messieurs, vous avez eu le verdict du juge !

Et notre trophée a deux gants : un pour chaque concurrent.

Le trophée 'GraphQL dans WordPress'

Mais quel est votre verdict ?

Continuerez-vous à utiliser WPGraphQL sans condition pour vos besoins headless ?

Ou donnerez-vous à Gato GraphQL l'opportunité qu'il réclame, téléchargerez le plugin, et lui donnerez-vous une chance ?


Mesdames et messieurs. C'est tout pour ce soir.

Nous espérons sincèrement que vous avez apprécié le combat.

Et espérons avoir une nouvelle rencontre prochainement entre nos deux champions.

Bonne nuit.

Mise à jour 01/05/2024 : Apprenez-en plus dans la comparaison Gato GraphQL vs WPGraphQL.


Abonnez-vous à notre newsletter

Restez au courant de toutes les nouveautés de Gato GraphQL.