🥊 Gato GraphQL vs WPGraphQL: il combattimento!
Aggiornamento 01/05/2024: Scopri il confronto Gato GraphQL vs WPGraphQL.
Signoreeeeeeeeee e signori.

Benvenuti alla MGM Grand Garden Arena per l'incontro del secolo! Stasera, facciamo la storia. Due giovani combattenti si affronteranno sul ring, scontrandosi per il premio per cui hanno lavorato così duramente:
Diventare il campione del mondo di "GraphQL in WordPress" 🏆
Alla nostra destra, abbiamo il campione in carica. Anche se ha solo 4 anni, è già pieno di esperienza, avendo recentemente raggiunto la versione 1.0 ed essendo stato pubblicato nella directory di wp.org, ed è molto popolare tra la folla.
🥁 Diamo 🥁 il 🥁 benvenuto 🥁 aaaa 🥁 ...... WPGraphQL!

Alla nostra sinistra, abbiamo lo sfidante. È nel mondo da appena 1 mese, ma è molto energico e ambizioso, mostrando la sua forza fin dal primo giorno. È stato lui a cercare l'incontro di oggi. Stasera è la sua occasione, e il mondo sta prestando attenzione.
🥁 Diamo 🥁 il 🥁 benvenuto 🥁 aaaa 🥁 ...... Gato GraphQL!

Stasera, i nostri contendenti si incontreranno faccia a faccia per la prima volta, in un incontro di 12 round. Mentre prendono posizione al centro del ring, in attesa del gong d'apertura, si studiano a vicenda, cercando di trovare i punti vulnerabili dell'altro. Tuttavia, mostrano solo sicurezza.

Chi prevarrà? WPGraphQL manterrà il suo vantaggio, basato sul sostegno dei suoi seguaci? Oppure il nuovo arrivato Gato GraphQL convincerà una comunità ignara della potenza dei suoi pugni, lasciando una scia di stupore che converte la folla dalla sua parte?
Stasera, signore e signori, lo scopriremo.
Fate le vostre scommesse. E godetevi l'incontro!
🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣
Mi è stato recentemente chiesto di spiegare le differenze tra il mio plugin, Gato GraphQL, e WPGraphQL.
Entrambi i plugin sono server GraphQL per WordPress, quindi servono allo stesso scopo. Tuttavia, sotto il cofano hanno caratteristiche diverse, il che può rendere uno migliore dell'altro per soddisfare un determinato comportamento richiesto.
Anche se sono di parte verso il mio stesso plugin, ho cercato di tracciare un confronto equo, basato su argomenti che considero importanti sia per GraphQL sia per WordPress. (Se i lettori desiderassero un confronto su un altro argomento, sarò felice di accontentarli.)
Il confronto non è esaustivo. Per esempio, mi piacerebbe anche fare qualche benchmark, misurando la velocità di risoluzione della stessa query GraphQL con entrambi i server. (Se i lettori trovano questa proposta interessante, posso farlo per un prossimo articolo.)
Ho diviso il mio confronto in 4 aree principali: Popolarità, Stile di codice e standard, Questioni pressanti e Ampliare la portata, con 3 elementi per ciascuna, per un totale di 12 "round". Alla fine, i giudici emettono il loro verdetto, per nominare il campione.
Clicca qui sotto per saltare direttamente a un argomento:
🔔 Ding 🔔 ding 🔔 diiiiiing...
Il gong d'apertura è suonato...
L'incontro è iniziato!
Popolarità
Qualsiasi software (o tecnologia, se è per questo) deve essere usato dalle persone, altrimenti il fatto che sia migliore delle alternative sarà solo un aneddoto.
Per esempio, anche se esistono alternative che permettono di digitare più velocemente, usiamo ancora principalmente la tastiera QWERTY.
Quanto sono popolari i due plugin?
Round 1: Chi lo usa, e quanto è completo
WPGraphQL è stato, finora, sinonimo di GraphQL in WordPress. Durante gli oltre 4 anni in cui è stato sviluppato (a partire da novembre 2016), ha raccolto oltre 2,8k stelle sul repository, una comunità di oltre 4600 follower e quasi 100 contributori al progetto.
Ha raggiunto la versione 1.0 ed è stato caricato nella directory dei plugin su wp.org a novembre 2020. Da allora, ha raccolto oltre 8000 installazioni attive. È attualmente l'unica soluzione per recuperare contenuti WordPress in Gatsby e, più recentemente, diversi progetti lo hanno aggiunto ai loro stack, tra cui il framework Headless di WPEngine e lo starter WordPress Next.js di WebDevStudios.
In altre parole, WPGraphQL è popolare.
Lo sviluppo di Gato GraphQL è iniziato seriamente circa 1,5 anni fa (come parte di un progetto più ampio), e ha raggiunto uno stato "abbastanza buono" 6 mesi fa, ricevendo 150 stelle sul repository da allora. Il plugin è attualmente alla versione 0.7, e gli mancano ancora diversi mesi prima di raggiungere la 1.0 (per esempio, non ha ancora le categorie nello schema).
Il mese scorso ho lanciato questo sito attuale gatographql.com, e da allora ho promosso il plugin tramite il blog (come l'articolo che stai leggendo ora), e ho anche pubblicato un articolo introduttivo su CSS-Tricks. Questi tentativi hanno portato diverse centinaia di persone sul sito, e oltre 100 visitatori hanno scaricato il plugin.
In altre parole, Gato GraphQL sta lentamente ma costantemente diventando popolare, ed è un lavoro in corso.
Vincitore del round: WPGraphQL.

Round 2: Disponibilità di estensioni
Le estensioni permettono di interagire con altri plugin tramite Gato GraphQL.
WPGraphQL dispone di estensioni per ACF, WooCommerce, Yoast e alcune altre.
Gato GraphQL non ha ancora estensioni, e non mi aspetto che ce ne saranno molte prima del rilascio della versione 1.0.
Tuttavia, Gato GraphQL pone una grande enfasi sulle estensioni nella sua architettura, permettendo all'utente di gestirle (attivare, disattivare, configurare e leggere la loro documentazione) da un luogo centrale, la pagina "Modules":

In altre parole, mentre WPGraphQL ha già estensioni, Gato GraphQL sta preparando il terreno per esse.
Vincitore del round: WPGraphQL.

Round 3: Pubblico di riferimento
WPGraphQL si rivolge agli sviluppatori: se vuoi estrarre dati dal tuo sito WordPress, devi memorizzare la tua query GraphQL da qualche parte nel tuo codice (molto probabilmente, in qualche funzione JavaScript). Poi, per poterla usare, devi essere abbastanza bravo a programmare.
Gato GraphQL, invece, segue la filosofia di WordPress secondo cui chiunque dovrebbe poterlo usare, inclusi i non tecnici. Per raggiungere questo obiettivo, permette di creare e gestire una query GraphQL tramite l'editor di WordPress, in modo che rendere accessibili i dati del sito WordPress tramite un'API diventi facile come creare un articolo del blog.
Inoltre, Gato GraphQL pone maggiore enfasi nell'offrire client per interagire con il servizio GraphQL in modo visivo. Mentre entrambi i plugin forniscono il client GraphiQL, per eseguire la query, solo Gato GraphQL fornisce anche il client Voyager, per esplorare interattivamente lo schema:

Vincitore del round: Gato GraphQL.

Stile di codice e standard
Parliamo di codice!
Se stai usando GraphQL, è probabile che tu stia facendo WordPress headless e renderizzando il sito web usando qualche framework JavaScript, che è un paradigma moderno. Inoltre, WordPress sarà anche un vecchio CMS, ma GraphQL è un'interfaccia moderna per accedere ai dati del sito. Quindi, posso tranquillamente supporre che tu sia uno sviluppatore avveduto, desideroso di produrre codice elegante, e che non accetterai di usare una soluzione subottimale.
Quanto è elegante il codice (della loro stessa codebase, e atteso dalle nostre implementazioni personalizzate) di questi due plugin?
Round 4: Requisiti PHP
Sia WPGraphQL sia Gato GraphQL richiedono PHP 7.1+.
Tuttavia, c'è una differenza: Gato GraphQL è in realtà codificato usando PHP 7.4, e viene poi transpilato a PHP 7.1 per la produzione.
Quindi, programmare Gato GraphQL è molto più piacevole: puoi usare funzionalità PHP più recenti, tra cui il tipo object, le proprietà tipizzate e le arrow function. E una volta aggiunto il supporto per PHP 8.0 (cosa che avverrà quando sarà rilasciata la nuova versione di Lando), potrai usare anche gli union type, l'espressione match, e altre.
Vincitore del round: Gato GraphQL.

Round 5: Pratiche di codifica
Cominciamo con WPGraphQL. Andando sul repository wp-graphql/wp-graphql, c'è qualcosa che mi salta all'occhio:

Ingrandendo:

Mi dispiace, ma c'è solo un modo in cui posso reagire a questo:

Committare la cartella vendor di Composer nel repository è una cattiva pratica, e Composer lo sconsiglia esplicitamente.
Risolvere questo problema non è difficile (ho persino descritto un modo basato sulle GitHub actions), quindi mi chiedo perché sia lì.
Direi che, in questo round, WPGraphQL sta colpendo se stesso!

Continuiamo. Sviluppare per WPGraphQL richiede di conoscere una collezione super estesa di hook (azioni e filtri). Andando alla referenza per sviluppatori di WPGraphQL, possiamo apprezzarne l'ampiezza.
Per fare uno screenshot della lista delle azioni, ho dovuto rimpicciolire il browser al 50%:

Per la lista dei filtri, ho rimpicciolito al 30% (il minimo che Firefox supporta), e nemmeno così sono riuscito a ottenere la lista completa:

Passiamo al repository GatoGraphQL/GatoGraphQL, che è il monorepo contenente Gato GraphQL (tra gli altri progetti).
Queste sono alcune delle caratteristiche del codice:
✅ Conforme agli standard PSR-1, PSR-4 e PSR-12.
✅ Tutto il codice è suddiviso in più package atomici, e tutti (oltre 100 per il plugin, oltre 200 per l'intero progetto) sono ospitati nello stesso monorepo.
✅ Usa Composer per gestire tutte le dipendenze.
✅ Usa Symfony Dependency Injection per gestire tutti i servizi dell'applicazione. Per registrare un nuovo type resolver, field resolver o directive resolver, dobbiamo semplicemente registrare un nuovo servizio nel container.
✅ Ogni classe è un servizio, e Symfony Dependency Injection si occupa di assemblare automaticamente l'intera applicazione.
✅ Il server GraphQL sottostante è CMS-agnostic. Gato GraphQL implementa i contratti per WordPress, e aggiunge un po' di logica personalizzata (per esempio, per fornire i client).
Il codice specifico per WordPress è solo circa il 10% del codice complessivo. Replicare questo 10% per un altro framework o CMS (Laravel/Drupal/ecc) può fornire un'implementazione di un server GraphQL anche per loro.
✅ Come conseguenza dell'essere CMS-agnostic, programmare un resolver implica programmare la sua logica di business generica, alimentata da servizi riutilizzabili. Non pensiamo mai in termini di codice WordPress, e raramente dobbiamo gestire il suo debito tecnico.
✅ Allo stesso modo, lo schema GraphQL non è una replica 1:1 del modello di dati di WordPress, aggirando il debito tecnico accumulato da WordPress a livello del layer dei dati, e fornendo un'interfaccia pulita.
✅ Il problema N+1 di GraphQL non può verificarsi, per progettazione architetturale, e senza disturbare affatto lo sviluppatore.
✅ Il server non è solo un server GraphQL: è in realtà un server API, dove la risposta può essere prodotta in altri formati o specifiche (es: REST) da un'unica fonte di verità. (Maggiori dettagli nel round 11).
✅ Nessuna directory vendor viene committata. Invece, il codice sorgente viene trasformato in codice di distribuzione (cioè il plugin finale da installare sul sito WordPress) tramite GitHub actions, e distribuito verso un repository dist, dove contiene effettivamente la cartella vendor.
✅ Durante la generazione del codice per la distribuzione, esso viene scopato con PHP-Scoper, e il codice sorgente, che contiene codice PHP 7.4, viene transpilato a PHP 7.1.
✅ Poiché ha risolto lo scoping, il plugin può fare affidamento su qualsiasi dipendenza di terze parti. Attualmente, fa uso di DependencyInjection di Symfony, Cache e Dotenv, Guzzle (per interagire con API esterne), il Pipeline della League, e diversi altri.
Questo è importante non solo per il presente, ma anche per il futuro: posso avere la certezza di poter usare qualsiasi dipendenza dal repository Packagist, quindi non ho bisogno di reinventare la ruota.
✅ I campi sono sottoscritti ai tipi, rendendo lo schema GraphQL facile da estendere.
Vincitore del round: Gato GraphQL (di gran lunga, oserei dire, se non ti dispiace).

Round 6: Estendere lo schema
Aggiungiamo un campo allo schema GraphQL.
Seguiamo il tutorial per WPGraphQL. Il codice suggerito è quello qui sotto. Dichiara un action hook per eseguire una funzione che dichiara un array. Sia la descrizione dei campi sia la loro risoluzione sono forniti all'interno dell'array:
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';
},
]);
});Questo esempio è il più semplice possibile: il resolver praticamente non fa nulla. Eppure, faccio già fatica a guardare il codice e a capire al volo cosa faccia. No, non sto facendo il sarcastico: tutti i colori di quel codice nel mio editor si contendono la mia attenzione. Inoltre, non c'è separazione delle responsabilità, e il codice non sembra molto riutilizzabile.
Quindi, spetterà allo sviluppatore (cioè a te) rendere il codice facile da leggere, riutilizzabile, privo di bug, e molto altro, mentre sviluppi l'applicazione; la libreria stessa non sembra aiutare molto a questo riguardo.
Chiamo questo stile "ADD": Array-Driven Development. Non posso dire di esserne un fan.
(Per essere equi verso WPGraphQL, questa è una pratica di codifica standard, ed è anche quella adottata dal motore sottostante webonyx/graphql-php.)
In Gato GraphQL, tutto il codice è SOLID. Per registrare un campo nello schema GraphQL, creiamo una classe che implementa l'interfaccia FieldResolverInterface (in realtà, estendendo AbstractSchemaFieldResolver, che ha già molti metodi implementati), e la registriamo nel container.
Per esempio, questo codice fornisce i campi username, email e url al tipo 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;
}
}Credo che la mia soluzione sia più elegante di quella di WPGraphQL. Tuttavia, è una questione di gusti. So che molti sviluppatori non sono infastiditi dall'Array-Driven Development, e anzi lo preferiscono perché, in un blocco di codice compatto, possono implementare tutta la logica.
Vincitore del round: è un pareggio.

Intervallo
Che notte abbiamo, signore e signori.

Abbiamo raggiunto la metà dell'incontro, quindi questo è un buon momento per una pausa bagno, e per fare qualche commento su ciò che abbiamo vissuto finora.
(Nel frattempo, dovrei mostrare una pubblicità dei miei sponsor. Purtroppo, non ne ho ancora. Se desideri che la tua azienda finanzi lo sviluppo di Gato GraphQL, e ottenga visibilità in media di primo piano come questo evento, inviami un messaggio.)

Che incontro abbiamo! WPGraphQL all'inizio era tutto fuoco e furia! Ha cominciato l'incontro in gran forma, assestando colpi terribilmente potenti a Gato GraphQL, che riusciva a malapena a stare in piedi sulle due gambe. Colpo dopo colpo dopo colpo. Non avrei voluto essere nei panni di Gato GraphQL.
Devo ammettere, ho pensato che dopo i primi 2 round, l'incontro sarebbe presto finito. Mi aspettavo il knock-down da un momento all'altro. Di vedere un asciugamano ondeggiante chiedere pietà. Ma Gato GraphQL ha resistito. Bisogna riconoscerglielo. Che determinazione incrollabile, è davvero notevole!
E poi, è avvenuta la trasformazione. A partire da qualche punto del 3° round, Gato GraphQL sembrava trarre energie dal nulla, e ha cominciato non solo a difendersi, ma a restituire i pugni, molti dei quali sono andati a segno sul viso di WPGraphQL. Ho visto WPGraphQL tremare e vacillare! Non avevamo mai visto nulla del genere dal nostro attuale campione del mondo. Che trasformazione davvero notevole abbiamo appena vissuto!
E poi, avendo scosso la sicurezza del suo avversario, a partire dal 4° round Gato GraphQL si è preso la briga di assestare una serie di colpi letali. È stato sorprendente! Per fortuna ad affrontarlo c'è il nostro campione del mondo, WPGraphQL, che è riuscito a reggere i colpi, sollevato dalle acclamazioni e dalla compassione della folla. Che eroe! Chiunque altro sarebbe soccombuto all'istante, ma non lui, ha sopportato i colpi da campione qual è.
Ma campione, lo sarà ancora a lungo? Nessuno è ancora andato KO, nessuno ha ancora gettato l'asciugamano. L'incontro potrebbe in qualsiasi momento prendere una svolta decisiva. I due combattenti sanno cosa vogliono, e sono sicuro che torneranno di nuovo con tutta la loro potenza, e tutta la loro determinazione, per scagliarsi contro il loro avversario, per prevalere.
Che incontro abbiamo!
E ora, signore e signori, i due guerrieri tornano sul ring.

Avanti con il resto dell'incontro!
Questioni pressanti
Il server GraphQL deve prestare attenzione a molte considerazioni, solo per soddisfare la proposta "recupera i dati di cui hai bisogno, né più né meno".
Per esempio:
- Quanto è sicuro? Come ci assicuriamo di non esporre dati privati su un endpoint pubblico?
- Quanto è performante? Come possiamo ridurre il carico sul server quando inviamo ripetutamente la stessa query, rendendolo allo stesso tempo il più veloce possibile?
- Quanto è semplice? Quanto è ben integrato con WordPress, in modo da sfruttare le funzionalità fornite dal CMS?
E molte altre domande. Questo è solo un piccolo campione che ho scelto, e che affronterò nei 3 round seguenti.
Round 7: Persisted queries
Le persisted queries combinano il meglio di GraphQL e REST: vengono create usando GraphQL, quindi non c'è sotto/sovra-recupero di dati, ma vengono pubblicate sul server come un endpoint, con il proprio URL.
Le persisted queries offrono questi vantaggi:
✅ È sicuro: invece di dare accesso a qualsiasi dato attraverso l'unico endpoint, possiamo predefinire quali dati esporre.
✅ È veloce: essendo accessibile tramite il proprio URL, può essere messo in cache su ogni livello tra il client e i back-end (nel server, CDN, browser) usando l'HTTP caching standard.
WPGraphQL offre il supporto per le persisted queries tramite queste due estensioni:
Inoltre, Jason Bahl (creatore di WPGraphQL) ha recentemente annunciato che nel prossimo futuro aggiungerà il supporto per le persisted queries in WPGraphQL.
Mi chiedo cosa abbia in mente, dato che ci sono già le 2 estensioni. In cosa sarà diverso da quelle? Forse vuole renderlo parte del core del plugin, per rafforzare le misure di sicurezza complessive del plugin senza dipendere da una terza parte?
O forse ha visto l'implementazione di Gato GraphQL, e vuole fornire un'esperienza simile, gestendola tramite un editor visivo invece che con puro codice?
Il che ci porta a Gato GraphQL. Non solo offre persisted queries, ma si è impegnato a renderle una parte centrale dell'offerta:
✅ Il plugin permette di disabilitare l'unico endpoint, e gli utenti sono incoraggiati a esporre i dati solo tramite persisted queries.
(Al contrario, WPGraphQL si limita a disabilitare l'introspezione per impostazione predefinita, non l'endpoint vero e proprio. In altre parole, gli attaccanti possono comunque essere in grado di accedere ai dati privati; gli si rende solo il compito più difficile, dato che non sapranno in anticipo quali dati privati ci sono.)
✅ È profondamente integrato con l'editor di WordPress, così che creare una persisted query richiede lo stesso sforzo di creare un articolo del blog, e chiunque può farlo, non solo i programmatori.
✅ Le persisted queries non sono statiche: possono usare variabili GraphQL, il cui valore può essere fornito tramite parametri URL durante l'esecuzione dell'endpoint.
Dai un'occhiata all'esperienza di creazione ed esecuzione di una persisted query nel mio plugin:
Vincitore del round: Gato GraphQL.
Round 8: Caching
GraphQL ha un grosso punto debole: non è facilmente memorizzabile in cache. Il motivo è che dipende dall'invio di operazioni POST a un unico endpoint. Poiché l'unico endpoint produrrà risultati diversi, e poiché la query viene inviata nel corpo della richiesta invece che nei parametri URL, allora non possiamo avere l'unico endpoint messo in cache.
La soluzione standard offerta da molti server GraphQL è spostare il caching sul client, e fare affidamento sugli ID degli oggetti come identificatori dell'entità da mettere in cache invece dell'URL di un endpoint. La libreria più popolare che fornisce questa funzionalità è il client Apollo.
C'è una discussione sul repository di WPGraphQL su tutte le opzioni disponibili per il caching di WPGraphQL. È interessante notare che la maggior parte di esse sono strumenti esterni (come il client Apollo, o il WordPress Object Cache), il che significa aggiungere un livello extra all'applicazione, aumentandone la complessità, e rendendola possibilmente anche più lenta.
(Queste ragioni devono essere in parte dietro la decisione di implementare nativamente le persisted queries in WPGraphQL.)
Per esempio, il client Apollo gira, beh, sul client. Se accedi al sito web da un telefono cellulare di fascia bassa, senza molta potenza, quel codice JavaScript extra avrà un impatto sulle prestazioni dell'applicazione.
Allo stesso modo, gli sviluppatori che lavorano con WordPress possono essere competenti in PHP, ma non così tanto in JavaScript. Ora, mettere in cache le loro API significherà che dovranno preoccuparsi anche del livello JavaScript.
Gato GraphQL è stato più intelligente su questo argomento. Dato che fornisce persisted queries, il che significa che le query vengono eseguite sul proprio endpoint, permette di mettere in cache questi URL degli endpoint tramite l'HTTP caching.
L'header HTTP caching ha il valore max-age calcolato automaticamente a partire da tutti i valori max-age di tutti i campi della query, e questa informazione viene configurata usando l'editor di WordPress, campo per campo.
Di conseguenza, l'API può essere messa in cache su diversi livelli (nel client, CDN e server), ed è gestita nativamente all'interno del plugin, senza bisogno di aggiungere un altro livello.
Dai un'occhiata a questo video che mostra come gli endpoint API vengono messi in cache:
Vincitore del round: Gato GraphQL.
Round 9: Integrazione con Gutenberg
Un tempo Gutenberg era il futuro di WordPress. Non più: Gutenberg è ora il presente di WordPress (quindi possiamo riferirci ad esso come l'editor di WordPress), e il Full Site Editing è diventato il nuovo futuro.
Inutile dire che le nostre API devono avere una buona integrazione con l'editor di WordPress. Questo significa non solo recuperare e pubblicare dati per i blocchi, ma anche potenzialmente alimentare funzionalità nell'editor di WordPress stesso.
Per esempio, poiché le subscription GraphQL possono far inviare dati dal server al client in tempo reale, sarebbero adatte ad alimentare le funzionalità di editing collaborativo e di notifiche.
WPGraphQL può interrogare i dati dei blocchi tramite l'estensione WPGraphQL Gutenberg. Questa estensione crea un nuovo tipo per mappare ogni blocco, quindi abbiamo CoreParagraphBlock, CoreQuoteBlock, ecc.
Gato GraphQL potrà presto interrogare i dati dei blocchi (è un lavoro in corso). Tuttavia, invece di creare un nuovo tipo per blocco, avrà un unico tipo Block per rappresentare tutti i blocchi, e potremo poi estrarre i metadati specifici di un blocco in base al suo nome.
Per esempio, dai un'occhiata a come puoi tradurre il contenuto all'interno di un blocco paragrafo (usando la direttiva @strTranslate, che si connette all'API di 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")
}
}Vincitore del round: è un pareggio.
Ampliare la portata
"Ho un sogno."
I blocchi di Gutenberg sono stati concepiti per fornire un'interfaccia unica per creare contenuti in WordPress, semplificando enormemente lo sviluppo del codice per il CMS, e l'apprendimento richiesto agli utenti.
Pur essendo stati introdotti per creare contenuti, i blocchi stanno progressivamente prendendo il controllo di tutte le altre aree del CMS, inclusi i widget, i menu e, presto, i temi tramite il Full Site Editing. E in futuro, supporteranno anche le capacità multilingue e l'editing collaborativo (funzionalità a cui potremmo nemmeno pensare quando pensiamo ai blocchi), e chissà cos'altro.
Possiamo pensare a GraphQL negli stessi termini: come un'interfaccia unica per interagire con i dati. Questo significa, non solo recuperare e pubblicare dati, ma qualsiasi interazione che coinvolga dati, incluso l'editing.
WordPress ha un'occasione unica di diventare davvero il sistema operativo del web: un sistema alimentato da Gutenberg, che permette all'utente di inserire qualsiasi tipo di contenuto (testo, immagini, video, audio, ecc), elaborarlo tramite i propri strumenti o qualche servizio basato sul cloud, e pubblicarlo verso la sua destinazione finale, che sia il sito WordPress o altrove.
Ma dietro questo potente sogno, ci deve essere un'API davvero potente, per soddisfare qualsiasi requisito le imponiamo. Un'API che potrebbe essere basata su GraphQL, ma che sia stata progettata anche per trascenderne i limiti.
Round 10: Supporto per le direttive personalizzate

WPGraphQL non viene fornito con una singola direttiva. Non sto dicendo che non le supporti (il suo motore webonyx/graphql-php lo fa), ma che non offre un'implementazione di alcuna direttiva personalizzata.
"E allora?" potresti pensare. "A cosa ci servono le direttive? Se qualcuno ha bisogno di modificare il risultato della query, può farlo sul proprio client!"

Questa è una questione di opinione, e non c'è giusto o sbagliato. Ma lascia che ti dica una cosa: le direttive sono una funzionalità incredibilmente utile, una di quelle che aiutano a distinguere GraphQL da REST. Se non le stai usando, molto probabilmente non stai sfruttando al massimo la tua API.
Le direttive sono non regolamentate dalla spec, quindi i server GraphQL possono implementarle come preferiscono, renderle potenti quanto serve. Ecco perché molte nuove funzionalità di GraphQL vengono introdotte per la prima volta tramite direttive, come @stream e @defer.
Gato GraphQL tratta le direttive con riverenza. Vengono eseguite una sola volta con i dati di tutte le entità, per tutti i campi a cui sono applicate (il che spiega perché la direttiva @strTranslate può recuperare i risultati dall'API di Google Translate così rapidamente), e il motore GraphQL stesso è basato su una pipeline di direttive.
Ahhhh, ma hai paura di rendere disponibile tutta questa potenza agli utenti, vero? È una preoccupazione legittima. Ma allora, puoi semplicemente rimuovere l'accesso all'unico endpoint, e fornire l'accesso ai dati solo tramite persisted queries, dove tu (l'amministratore del sito) sei l'unica persona ad avere accesso alle direttive.
Quindi o ne benefici, o non succede nulla.
Se ami le direttive, fantastico, adorerai Gato GraphQL! ❤️
Ma, d'altra parte, se non ti piace, non succede nulla.
Vincitore del round: Gato GraphQL.
(Se credi che "non abbiamo bisogno di queste maledette direttive", per favore non prendertela con me... Sto solo facendo il mio lavoro.)
Round 11: Supporto per REST
"Ahhhhh? REST? Quale REST? Non stiamo parlando di GraphQL qui? Perché parli di REST allora? Perché vuoi complicarmi la vita?"

Sì, a prima vista questo argomento sembra fuori luogo. Ma l'ho aggiunto in questo confronto per una ragione molto semplice: Matt Mullenweg ha detto che sta valutando GraphQL per una potenziale inclusione nel core di WordPress, e l'unica cosa di cui i contributori si preoccuperanno è dover mantenere due codebase.
Il che porta alla domanda ovvia: il server GraphQL può gestire anche REST?
La risposta è "parzialmente sì" per WPGraphQL, e "completamente sì" per Gato GraphQL.
Riguardo a WPGraphQL. È possibile definire un endpoint REST che, quando viene risolto, esegue semplicemente una query GraphQL contenente i campi richiesti, sia come chiamata interna al motore GraphQL, sia come operazione POST esterna eseguita contro lo stesso web server.
Ma questo non basta per soddisfare la WP REST API, perché essa ha anche uno schema JSON, e non possiamo farne a meno.
Riguardo a Gato GraphQL. Devo ammettere che sono stato fortunato, perché il lavoro sul suo motore sottostante (il modello a componenti lato server chiamato PoP) è iniziato intorno al 2013, cioè diversi anni prima che conoscessi qualcosa chiamato GraphQL, e questo progetto si è evoluto con alcune idee proprie (che ho documentato in questo mio articolo vintage).
Poi, quando ho iniziato a programmare il server GraphQL CMS-agnostic (su cui poggia Gato GraphQL) circa 1,5 anni fa, ho unito le idee sviluppate per PoP con le fondamenta stabilite da GraphQL, creando un sistema che supporta interamente la spec GraphQL, pur essendo in grado di aggiungervi un diverso insieme di funzionalità.
A questo riguardo, lo schema che PoP usa è API-agnostic, ed è un sovrainsieme di quello di GraphQL. Lo schema PoP si trova sotto /api/graphql/?query=fullSchema.
Poi, il layer del server GraphQL formatta lo schema PoP seguendo la specifica GraphQL, il che produce lo schema GraphQL. E allo stesso modo, possiamo produrre lo schema JSON richiesto dalla WP REST API.
Generare questo schema JSON non è stato ancora fatto, ma è fattibile.
Ciò che è già stato fatto, è produrre la risposta della query in più formati. Per esempio, questa query GraphQL:
{
posts {
id
title
date
author {
name
}
}
}Viene risolta anche tramite questo endpoint REST: /posts/api/rest/?query=id|title|date|author.name.
E non c'è bisogno di fermarsi qui. Hai bisogno di produrre i risultati usando un formato ancora diverso, come XML? No problemo: /api/?query=posts.id|title|date|author.name&datastructure=xml.
(Questo potrebbe aiutare a implementare la proposta di un nuovo strumento di import/export per WordPress, basato su uno schema. Questo rende anche un po' più evidente ciò che ho detto prima: una singola interfaccia può alimentare tutte le interazioni con i dati, sia all'interno del CMS, sia dal CMS verso API esterne.)
Vincitore del round: Gato GraphQL.
Round 12: Supporto per funzionalità innovative
La spec GraphQL è definitiva? La risposta è no: la spec è in costante evoluzione. In questo momento, ci sono 100 issue aperte, molte delle quali contengono proposte che verranno formalizzate prima o poi in futuro.
Ora, tra queste 100 issue, ci saranno certamente nuove funzionalità di cui possiamo beneficiare oggi, giusto? Se è così, perché aspettare?
Questo è esattamente il mio modo di pensare.

"Ma se qualcosa non è nella spec GraphQL, allora non dovremmo aggiungerlo al server GraphQL, o gli utenti si confonderanno!"
Buon punto. Tuttavia, se rendiamo le nuove funzionalità disponibili solo come opt-in, allora gli utenti ne saranno necessariamente consapevoli, e non si verificherà alcun problema o malinteso.
Ancora una volta, questo è il mio modo di pensare. Si tratta però di una questione di opinione, quindi se preferisci usare solo funzionalità che ogni singolo server GraphQL là fuori sta usando, va bene.
Credo che WPGraphQL operi così. Almeno, non ho visto una singola funzionalità che vada oltre ciò che è stato approvato nella spec.
Per Gato GraphQL, invece, scansiono regolarmente la lista delle issue nella spec e, se trovo qualche funzionalità interessante, che può essere soddisfatta dal mio server senza troppo sforzo, allora la implemento. (In effetti, questo è uno dei miei hobby.)
Queste sono le funzionalità "rivolte al futuro" che ho implementato finora:
✅ Esecuzione di query multiple
✅ Namespacing dello schema
✅ Mutation annidate
✅ Direttive componibili
✅ Feedback proattivo
✅ Versionamento basato su campi e direttive
E sto già pianificando di aggiungere:
✳️ Subscription (questa fa già parte della spec)
✳️ Direttive @stream e @defer
✳️ Sintassi a catena piatta
Vincitore del round: Gato GraphQL.
Verdetto!
Signore, signori.

Che notte indimenticabile abbiamo vissuto! Che incontro abbiamo appena vissuto! Due pesi massimi che hanno dato il meglio di sé per il loro sogno.
Un sogno che entrambi inseguono, ma che solo uno può afferrare.
E ora, sapremo chi è quella persona. Ora, è il momento della verità!
Chi sarà il campione del mondo di "GraphQL in WordPress"?
Sarà l'acclamatissimo, amato dalle masse, presente nelle grandi pubblicazioni campione in carica, WPGraphQL?
O sarà l'irriverente, pesta-i-piedi-senza-chiedere-scusa, arriva-non-invitato-alla-festa sfidante, Gato GraphQL?

Stiamo aspettando il verdetto del giudice. Che tensione! Oh Santa Maria, fai resistere il mio cuore a questo momento!
🥁 E 🥁 il 🥁 vincitore 🥁 èèèèèèèèèèèèè 🥁 ...
È un pareggio!
I 2 combattenti, i 2 pesi massimi, hanno pareggiato!

Che momento meraviglioso! I due contendenti si abbracciano, dimostrando che siamo tutti amici all'interno della comunità WordPress, come una grande famiglia che siamo.
Allora, qual è la giustificazione del pareggio? Il giudice spiega:
👑 WPGraphQL è il più popolare, e il suo utilizzo è più diffuso.
👑 Gato GraphQL ha un'architettura migliore, e potrebbe potenzialmente servire meglio WordPress sul lungo periodo.
Signore e signori, avete avuto il verdetto del giudice!
E il nostro trofeo ha due guantoni: uno per ciascun contendente.

Ma qual è il tuo verdetto?
Continuerai a usare WPGraphQL senza condizioni per le tue esigenze headless?
Oppure darai a Gato GraphQL l'opportunità che reclama, scaricherai il plugin, e gli darai una chance?
Signore e signori. È tutto per stasera.
Speriamo sinceramente che abbiate apprezzato l'incontro.
E speriamo di avere presto un nuovo incontro tra i nostri due campioni.
Buonanotte.
Aggiornamento 01/05/2024: Scopri di più nel confronto Gato GraphQL vs WPGraphQL.