Blog

🥊 Gato GraphQL vs WPGraphQL: a luta!

Leonardo Losoviz
Por Leonardo Losoviz ·

Atualização 01/05/2024: Confira a comparação Gato GraphQL vs WPGraphQL.

Senhoooooooooras e senhores.

Anunciando a próxima luta

Bem-vindos à MGM Grand Garden Arena para o combate do século! Esta noite, estamos fazendo história. Dois jovens lutadores vão se enfrentar no ringue, disputando o prêmio pelo qual trabalharam tanto:

Se tornar o campeão mundial de "GraphQL no WordPress" 🏆

À nossa direita, temos o atual campeão. Apesar de ter apenas 4 anos, já está cheio de experiência, tendo recentemente chegado à versão 1.0 e sido publicado no diretório do wp.org, e é muito popular entre as multidões.

🥁 Deem 🥁 as 🥁 boas-vindas 🥁 aooo 🥁 ...... WPGraphQL!

O atual campeão, WPGraphQL

À nossa esquerda, temos o desafiante. Está no mundo há apenas 1 mês, mas é muito enérgico e ambicioso, exibindo sua força desde o primeiro dia. Foi ele quem buscou o encontro de hoje. Esta noite é sua chance, e o mundo está prestando atenção.

🥁 Deem 🥁 as 🥁 boas-vindas 🥁 aooo 🥁 ...... Gato GraphQL!

O desafiante, Gato GraphQL

Esta noite, nossos contendores se encontrarão frente a frente pela primeira vez, em uma luta de 12 rounds. Enquanto tomam suas posições no centro do ringue, aguardando o sino de abertura, eles se estudam mutuamente, tentando encontrar os pontos vulneráveis um do outro. No entanto, demonstram apenas confiança.

Os 2 gloriosos lutadores se estudam mutuamente

Quem vai prevalecer? O WPGraphQL vai manter sua vantagem, baseada no apoio de seus seguidores? Ou o novato Gato GraphQL vai convencer uma comunidade desavisada do poder de seus punhos, deixando um rastro de admiração que converte as multidões para o seu lado?

Esta noite, senhoras e senhores, vamos descobrir.

Façam suas apostas. E aproveitem a luta!


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


Recentemente me pediram para explicar as diferenças entre o meu plugin, Gato GraphQL, e o WPGraphQL.

Ambos os plugins são servidores GraphQL para WordPress, portanto servem ao mesmo propósito. No entanto, por baixo do capô, eles têm características diferentes, o que pode tornar um melhor que o outro para satisfazer determinado comportamento requerido.

Embora eu seja parcial em relação ao meu próprio plugin, tentei traçar uma comparação justa, baseada em tópicos que considero importantes tanto para GraphQL quanto para WordPress. (Se os leitores desejarem uma comparação sobre outro tópico, ficará um prazer atender.)

A comparação não é exaustiva. Por exemplo, eu também gostaria de fazer alguns benchmarks, medindo a velocidade de resolução da mesma query GraphQL com os dois servidores. (Se os leitores acharem esta proposta atraente, posso fazê-la para um próximo artigo.)

Dividi minha comparação em 4 áreas principais: Popularidade, Estilo de código e padrões, Questões prementes e Ampliando o escopo, com 3 itens para cada uma, totalizando 12 "rounds". No final, os juízes emitem seu veredicto para nomear o campeão.

Clique abaixo para ir direto a algum tópico:

🔔 Ding 🔔 ding 🔔 diiiiiing...

O sino de abertura soou...

A luta começou!


Popularidade

Qualquer software (ou tecnologia, nesse caso) precisa ser usado pelas pessoas, caso contrário o fato de ser melhor que as alternativas será apenas uma anedota.

Por exemplo, embora existam alternativas que permitem digitar mais rapidamente, ainda usamos principalmente o teclado QWERTY.

Quão populares são os dois plugins?

Round 1: Quem está usando, e quão completo é

O WPGraphQL tem sido, até agora, sinônimo de GraphQL no WordPress. Durante os mais de 4 anos em que foi desenvolvido (a partir de novembro de 2016), acumulou mais de 2,8k estrelas no repositório, uma comunidade de mais de 4600 seguidores, e quase 100 contribuidores no projeto.

Chegou à versão 1.0 e foi publicado no diretório de plugins do wp.org em novembro de 2020. Desde então, acumulou mais de 8000 instalações ativas. É atualmente a única solução para buscar conteúdo WordPress no Gatsby e, mais recentemente, vários projetos o adicionaram às suas stacks, incluindo o framework Headless da WPEngine e o starter WordPress Next.js da WebDevStudios.

Em outras palavras, o WPGraphQL é popular.

O desenvolvimento do Gato GraphQL começou de forma séria há cerca de 1,5 anos (como parte de um projeto maior), e atingiu um status "bom o suficiente" há 6 meses, recebendo 150 estrelas no repositório desde então. O plugin está atualmente na versão 0.7, e ainda está a vários meses de chegar à versão 1.0 (por exemplo, ainda não possui categorias no schema).

No mês passado lancei este site atual gatographql.com, e desde então venho promovendo o plugin pelo blog (como o artigo que você está lendo agora), e também publiquei um artigo introdutório no CSS-Tricks. Essas iniciativas trouxeram algumas centenas de pessoas ao site, e mais de 100 visitantes baixaram o plugin.

Em outras palavras, o Gato GraphQL está crescendo em popularidade de forma lenta mas constante, e é um trabalho em andamento.

Vencedor do round: WPGraphQL.

É um golpe! O soco do WPGraphQL alcança o Gato GraphQL

Round 2: Disponibilidade de extensões

As extensões permitem interagir com outros plugins por meio do Gato GraphQL.

O WPGraphQL possui extensões para ACF, WooCommerce, Yoast e algumas outras.

O Gato GraphQL ainda não tem extensões, e não espero que haja muitas antes do lançamento da versão 1.0.

No entanto, o Gato GraphQL coloca grande ênfase em extensões em sua arquitetura, permitindo ao usuário gerenciá-las (ativar, desativar, configurar e ler sua documentação) a partir de um lugar central, a página "Modules":

Página Modules no Gato GraphQL

Em outras palavras, enquanto o WPGraphQL já tem extensões, o Gato GraphQL está preparando o terreno para elas.

Vencedor do round: WPGraphQL.

WPGraphQL golpeia de novo!

Round 3: Público-alvo

O WPGraphQL tem como alvo desenvolvedores: se você quiser extrair dados do seu site WordPress, precisará armazenar sua query GraphQL em algum lugar no código (muito provavelmente, em alguma função JavaScript). Depois, para poder usá-la, você precisará ser suficientemente bom em programação.

O Gato GraphQL, por outro lado, segue a filosofia do WordPress de que qualquer pessoa deve ser capaz de usá-lo, incluindo não técnicos. Para atingir esse objetivo, permite criar e gerenciar uma query GraphQL por meio do editor do WordPress, de modo que tornar os dados do site WordPress acessíveis via API se torna tão fácil quanto criar uma postagem no blog.

Além disso, o Gato GraphQL dá mais ênfase em oferecer clientes para interagir com o serviço GraphQL de forma visual. Enquanto ambos os plugins fornecem o cliente GraphiQL, para executar a query, apenas o Gato GraphQL também fornece o cliente Voyager, para explorar o schema de forma interativa:

Visualizando o schema GraphQL

Vencedor do round: Gato GraphQL.

Gato GraphQL desfere um bom golpe de esquerda!


Estilo de código e padrões

Vamos falar de código!

Se você está usando GraphQL, é provável que esteja fazendo WordPress headless e renderizando o site usando algum framework JavaScript, que é um paradigma moderno. Além disso, o WordPress pode ser um CMS antigo, mas o GraphQL é uma interface moderna para acessar dados do site. Portanto, posso assumir com segurança que você é um desenvolvedor criterioso, empenhado em produzir código elegante, e não aceitará usar uma solução abaixo do ideal.

Quão elegante é o código (da própria codebase deles, e esperado de nossas implementações personalizadas) desses dois plugins?

Round 4: Requisitos PHP

Tanto o WPGraphQL quanto o Gato GraphQL requerem PHP 7.1+.

No entanto, há uma diferença: o Gato GraphQL é na verdade codificado usando PHP 7.4, e depois transpilado para PHP 7.1 para produção.

Portanto, programar o Gato GraphQL é muito mais prazeroso: você pode usar recursos mais recentes do PHP, incluindo o tipo object, propriedades tipadas e arrow functions. E assim que o suporte para PHP 8.0 for adicionado (o que acontecerá quando a nova versão do Lando for lançada), você também poderá usar union types, a expressão match, entre outros.

Vencedor do round: Gato GraphQL.

O Gato GraphQL está deixando sua marca!

Round 5: Práticas de codificação

Vamos começar com o WPGraphQL. Acessando o repositório wp-graphql/wp-graphql, há algo que me chama a atenção:

A pasta vendor armazenada no repositório

Aproximando:

Conteúdo da pasta vendor

Desculpe, mas há apenas uma forma que posso reagir a isso:

Posso te perdoar muitas coisas na vida, mas não isso

Fazer commit da pasta vendor do Composer no repositório é uma má prática, e o Composer desencoraja isso explicitamente.

Corrigir esse problema não é difícil (eu até descrevi uma forma baseada em GitHub actions), então me pergunto por que está lá.

Diria que, neste round, o WPGraphQL está se golpeando!

Ai!

Continuando. Desenvolver para o WPGraphQL requer conhecer uma coleção superextensa de hooks (actions e filters). Acessando a referência para desenvolvedores do WPGraphQL, podemos apreciar a extensão disso.

Para tirar um screenshot da lista de actions, precisei diminuir o zoom do navegador para 50%:

Action hooks para estender o WPGraphQL

Para a lista de filters, diminuí para 30% (o mínimo que o Firefox suporta), e mesmo assim não consegui obter a lista completa:

Filter hooks para estender o WPGraphQL


Vamos mudar para o repositório GatoGraphQL/GatoGraphQL, que é o monorepo contendo o Gato GraphQL (entre outros projetos).

Estas são algumas das características do código:

✅ Em conformidade com os padrões PSR-1, PSR-4 e PSR-12.

✅ Todo o código é dividido em múltiplos pacotes atômicos, e todos eles (mais de 100 para o plugin, mais de 200 para o projeto inteiro) estão hospedados no mesmo monorepo.

✅ Usa o Composer para gerenciar todas as dependências.

✅ Usa o Symfony Dependency Injection para gerenciar todos os serviços da aplicação. Para registrar um novo type resolver, field resolver ou directive resolver, basta registrar um novo serviço no container.

✅ Cada classe é um serviço, e o Symfony Dependency Injection cuida de montar toda a aplicação automaticamente.

✅ O servidor GraphQL subjacente é CMS-agnostic. O Gato GraphQL implementa os contratos para WordPress e adiciona um pouco de lógica personalizada (por exemplo, para fornecer os clientes).

O código específico do WordPress é apenas cerca de 10% do código total. Replicar esses 10% para outro framework ou CMS (Laravel/Drupal/etc) pode fornecer uma implementação de um servidor GraphQL para eles também.

✅ Como consequência de ser CMS-agnostic, codificar um resolver implica codificar sua lógica de negócio genérica, alimentada por serviços reutilizáveis. Nunca pensamos em termos de código WordPress, e raramente precisamos lidar com sua dívida técnica.

✅ Da mesma forma, o schema GraphQL não é uma réplica 1:1 do modelo de dados do WordPress, contornando a dívida técnica acumulada pelo WordPress na camada de dados e fornecendo uma interface limpa.

✅ O problema N+1 do GraphQL não pode ocorrer, por design arquitetural, e sem incomodar o desenvolvedor de forma alguma.

✅ O servidor não é apenas um servidor GraphQL: na verdade, é um servidor de API, onde a resposta pode ser gerada em outros formatos ou especificações (ex: REST) a partir de uma única fonte de verdade. (Mais detalhes no round 11).

✅ Nenhuma pasta vendor é submetida ao repositório. Em vez disso, o código-fonte é transformado em código de distribuição (ou seja, o plugin final para instalar no site WordPress) via GitHub actions, e implantado em um repositório dist, onde contém a pasta vendor.

✅ Ao gerar o código para distribuição, ele é escopado com PHP-Scoper, e o código-fonte, que contém código PHP 7.4, é transpilado para PHP 7.1.

✅ Por ter resolvido o escoping, o plugin pode depender de qualquer dependência de terceiros. Atualmente, faz uso do DependencyInjection da Symfony, Cache e Dotenv, Guzzle (para interagir com APIs externas), o Pipeline da League, e vários outros.

Isso é importante não apenas para o presente, mas também para o futuro: posso ter a certeza de que posso usar qualquer dependência do repositório Packagist, então não preciso reinventar a roda.

Os campos são inscritos nos tipos, tornando o schema GraphQL fácil de estender.

Vencedor do round: Gato GraphQL (por uma grande margem, eu diria, se não se importar).

Após um round difícil, o WPGraphQL precisa de um descanso

Round 6: Estendendo o schema

Vamos adicionar um campo ao schema GraphQL.

Seguimos o tutorial para o WPGraphQL. O código sugerido é o abaixo. Ele declara um action hook para executar uma função que declara um array. Tanto a descrição dos campos quanto sua resolução são fornecidas dentro do 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';
		},
	]);
 
});

Este exemplo é o mais simples possível: o resolver praticamente não faz nada. Mesmo assim, já tenho dificuldade em olhar para o código e entender de imediato o que ele faz. Não, não estou sendo sarcástico: todas as cores daquele código no meu editor brigam pela minha atenção. Além disso, não há separação de responsabilidades, e o código não parece muito reutilizável.

Portanto, caberá ao desenvolvedor (ou seja, a você) tornar o código fácil de ler, reutilizável, livre de bugs e muito mais, enquanto desenvolve a aplicação; a própria biblioteca não parece ajudar muito nesse sentido.

Chamo esse estilo de "ADD": Array-Driven Development. Não posso dizer que sou fã.

(Para ser justo com o WPGraphQL, esta é uma prática de codificação padrão, e também é a adotada pelo motor subjacente webonyx/graphql-php.)


No Gato GraphQL, todo o código é SOLID. Para registrar um campo no schema GraphQL, criamos uma classe implementando a interface FieldResolverInterface (na verdade, estendendo de AbstractSchemaFieldResolver, que já tem muitos métodos implementados), e a registramos no container.

Por exemplo, este código fornece os campos username, email e url ao 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;
  }
}

Acredito que minha solução é mais elegante do que a do WPGraphQL. No entanto, é uma questão de gosto. Sei que muitos desenvolvedores não se importam com o Array-Driven Development, e na verdade o preferem porque, em um bloco compacto de código, conseguem implementar toda a lógica.

Vencedor do round: empate.

Empate


Intervalo

Que noite temos, senhoras e senhores.

Hora de analisar a luta até agora

Chegamos à metade da luta, portanto este é um bom momento para uma pausa no banheiro e fazer alguns comentários sobre o que vivenciamos até agora.

(Enquanto isso, deveria exibir um anúncio dos meus patrocinadores. Infelizmente, ainda não tenho nenhum. Se quiser que sua empresa financie o desenvolvimento do Gato GraphQL e obtenha exposição em mídia de primeira linha como este evento, me envie uma mensagem.)

Patrocine-me para ter acesso à publicidade de primeira linha para sua marca

Que luta estamos tendo! O WPGraphQL foi inicialmente todo fogo e fúria! Começou a luta em ótima forma, desferindo golpes terrivelmente poderosos no Gato GraphQL, que mal conseguia se manter de pé. Golpe após golpe após golpe. Eu não gostaria de estar no lugar do Gato GraphQL.

Preciso admitir, pensei que após os primeiros 2 rounds, a luta terminaria em breve. Estava esperando o nocaute a qualquer momento. Ver uma toalha sendo agitada pedindo misericórdia. Mas o Gato GraphQL resistiu. Temos que reconhecer isso nele. Que determinação inabalável, é verdadeiramente notável!

E então, a transformação aconteceu. Em algum momento a partir do 3º round, o Gato GraphQL pareceu obter energias do nada, e começou não apenas a se defender, mas a devolver os socos, muitos dos quais acertaram o rosto do WPGraphQL. Vi o WPGraphQL tremer e vacilar! Nunca tínhamos visto nada assim do nosso atual campeão mundial. Que transformação verdadeiramente notável acabamos de presenciar!

E então, tendo abalado a confiança de seu adversário, a partir do 4º round o Gato GraphQL tomou para si a tarefa de desferir uma série de golpes letais. Foi impressionante! Por sorte ele está enfrentando nosso campeão mundial, o WPGraphQL, que conseguiu suportar os golpes, encorajado pelas aclamações e compaixão das multidões. Que herói! Qualquer outro teria sucumbido na hora, mas não ele, ele aguentou os golpes como o campeão que é.

Mas campeão, ele será por quanto tempo mais? Ninguém foi nocauteado ainda, ninguém jogou a toalha ainda. A luta pode a qualquer momento tomar uma virada decisiva. Os dois lutadores sabem o que querem, e tenho certeza de que voltarão com toda a sua força e toda a sua determinação para atacar seu adversário e prevalecer.

Que luta estamos tendo!

E agora, senhoras e senhores, os dois guerreiros estão voltando para o ringue.

Os contendores estão voltando para o ringue

Vamos para o restante da luta!


Questões prementes

O servidor GraphQL precisa prestar atenção a muitas considerações, apenas para satisfazer a proposta "recupere os dados que você precisa, nem mais nem menos".

Por exemplo:

  • Quão seguro é? Como nos certificamos de que não estamos expondo dados privados em um endpoint público?
  • Quão performático é? Como podemos reduzir a carga no servidor ao enviar repetidamente a mesma query, tornando-o o mais rápido possível?
  • Quão simples é? Quão bem integrado está ao WordPress, para aproveitar os recursos fornecidos pelo CMS?

E muitas outras perguntas. Esta é apenas uma pequena amostra que escolhi e que abordarei nos 3 rounds seguintes.

Round 7: Persisted queries

As persisted queries combinam o melhor do GraphQL e do REST: são criadas usando GraphQL, portanto não há sub ou sobre-busca de dados, mas são publicadas no servidor como um endpoint, com sua própria URL.

As persisted queries oferecem estes benefícios:

✅ É seguro: em vez de dar acesso a qualquer dado pelo endpoint único, podemos pré-definir quais dados expor.

✅ É rápido: sendo acessado via sua própria URL, pode ser cacheado em cada camada entre o cliente e os back-ends (no servidor, CDN, navegador) usando o HTTP caching padrão.

O WPGraphQL oferece suporte a persisted queries por meio dessas duas extensões:

Além disso, Jason Bahl (criador do WPGraphQL) anunciou recentemente que em breve adicionará suporte a persisted queries no WPGraphQL.

Fico me perguntando o que ele tem em mente, já que existem as 2 extensões. Em que será diferente delas? Talvez queira torná-lo parte do core do plugin, para reforçar as medidas gerais de segurança sem depender de terceiros?

Ou talvez tenha visto a implementação do Gato GraphQL, e queira fornecer uma experiência semelhante, operando-a por meio de um editor visual em vez de código puro?

O que nos leva ao Gato GraphQL. Ele não apenas oferece persisted queries, como se esforçou para torná-las uma parte central da oferta:

✅ O plugin permite desabilitar o endpoint único, e os usuários são incentivados a expor dados apenas por meio de persisted queries.

(Em contraste, o WPGraphQL apenas desabilita a introspecção por padrão, não o endpoint em si. Em outras palavras, invasores ainda podem ser capazes de acessar dados privados; apenas se torna mais difícil para eles, já que não saberão com antecedência quais dados privados existem.)

✅ Está profundamente integrado ao editor do WordPress, de modo que criar uma persisted query exige o mesmo esforço de criar uma postagem no blog, e qualquer pessoa pode fazê-lo, não apenas programadores.

✅ As persisted queries não são estáticas: podem usar variáveis GraphQL, cujo valor pode ser fornecido por parâmetros de URL ao executar o endpoint.

Confira a experiência de criação e execução de uma persisted query no meu plugin:

Vencedor do round: Gato GraphQL.

Round 8: Caching

O GraphQL tem um grande ponto fraco: não é facilmente cacheável. O motivo é que depende do envio de operações POST para um único endpoint. Como o endpoint único produzirá resultados diferentes, e como a query é enviada no corpo da requisição em vez de parâmetros de URL, então não podemos ter o endpoint único sendo cacheado.

A solução padrão oferecida por muitos servidores GraphQL é transferir o caching para o cliente e depender dos IDs dos objetos como identificadores da entidade a ser cacheada em vez da URL de um endpoint. A biblioteca mais popular que fornece essa funcionalidade é o cliente Apollo.

Há uma discussão no repositório do WPGraphQL sobre todas as opções disponíveis para caching do WPGraphQL. Curiosamente, a maioria delas são ferramentas externas (como o cliente Apollo ou o WordPress Object Cache), o que significa adicionar uma camada extra à aplicação, aumentando sua complexidade e possivelmente tornando-a mais lenta.

(Essas razões devem estar parcialmente por trás da decisão de implementar persisted queries nativamente no WPGraphQL.)

Por exemplo, o cliente Apollo roda, bem, no cliente. Se acessar o site a partir de um celular de baixa potência, esse código JavaScript extra vai impactar o desempenho da aplicação.

Da mesma forma, desenvolvedores que trabalham com WordPress podem ser proficientes em PHP, mas não tanto em JavaScript. Agora, fazer cache de suas APIs significará que eles precisarão se preocupar também com a camada JavaScript.

O Gato GraphQL foi mais inteligente nesse tópico. Como fornece persisted queries, ou seja, as queries são executadas em seu próprio endpoint, permite cachear essas URLs de endpoint via HTTP caching.

O header de HTTP caching tem o valor max-age calculado automaticamente a partir de todos os valores max-age de todos os campos na query, e essa informação é configurada usando o editor do WordPress, campo por campo.

Como consequência, a API pode ser cacheada em várias camadas (no cliente, CDN e servidor), e é gerenciada nativamente dentro do plugin, sem necessidade de adicionar outra camada.

Confira este vídeo mostrando como os endpoints de API são cacheados:

Vencedor do round: Gato GraphQL.

Round 9: Integração com o Gutenberg

Costumava ser que o Gutenberg seria o futuro do WordPress. Não mais: o Gutenberg é agora o presente do WordPress (portanto podemos nos referir a ele como o editor do WordPress), e o Full Site Editing tornou-se o novo futuro.

Nem é preciso dizer que nossas APIs precisam ter uma boa integração com o editor do WordPress. Isso significa não apenas recuperar e publicar dados para blocos, mas também potencialmente alimentar recursos no próprio editor do WordPress.

Por exemplo, como as subscriptions GraphQL permitem que o servidor envie dados ao cliente em tempo real, seriam adequadas para alimentar os recursos de edição colaborativa e notificações.

O WPGraphQL pode consultar dados de blocos por meio da extensão WPGraphQL Gutenberg. Essa extensão cria um novo tipo para mapear cada bloco, então temos CoreParagraphBlock, CoreQuoteBlock, etc.

O Gato GraphQL em breve poderá consultar dados de blocos (está em desenvolvimento). No entanto, em vez de criar um novo tipo por bloco, terá um único tipo Block para representar todos os blocos, e então podemos extrair os metadados específicos de um bloco com base em seu nome.

Por exemplo, veja como você pode traduzir o conteúdo dentro de um bloco de parágrafo (usando a directive @strTranslate, que se conecta à API do 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")
  }
}

Vencedor do round: empate.


Ampliando o escopo

"Eu tenho um sonho."

Os blocos do Gutenberg foram concebidos para fornecer uma interface única para criar conteúdo no WordPress, simplificando enormemente o desenvolvimento do código para o CMS e o aprendizado exigido dos usuários.

Embora introduzidos para criar conteúdo, os blocos estão progressivamente assumindo todas as outras áreas do CMS, incluindo widgets, menus e, em breve, temas por meio do Full Site Editing. E no futuro, também suportarão capacidades multilíngues e edição colaborativa (funcionalidades que nem sequer pensamos quando pensamos em blocos), e quem sabe o quê mais.

Podemos pensar no GraphQL nos mesmos termos: como uma interface única para interagir com dados. Isso significa não apenas buscar e publicar dados, mas qualquer interação que envolva dados, incluindo edição.

O WordPress tem uma oportunidade única de realmente se tornar o SO da web: um sistema alimentado pelo Gutenberg que permite ao usuário inserir qualquer tipo de conteúdo (texto, imagens, vídeo, áudio, etc), processá-lo por meio de suas próprias ferramentas ou algum serviço baseado em nuvem, e publicá-lo em seu destino final, seja o site WordPress ou em outro lugar.

Mas por trás desse poderoso sonho, deve haver uma API verdadeiramente poderosa, para atender a qualquer requisito que lhe impomos. Uma API que poderia ser baseada em GraphQL, mas que foi projetada também para transcender suas limitações.

Round 10: Suporte a directives personalizadas

Início do round 10

O WPGraphQL não vem com uma única directive. Não estou dizendo que não as suporta (o motor webonyx/graphql-php suporta), mas que não oferece uma implementação de nenhuma directive personalizada.

"E daí?" você pode pensar. "Para que precisamos de directives? Se alguém precisar modificar o resultado da query, pode fazê-lo no próprio cliente!"

Por que preciso de directives?

Isso é uma questão de opinião, e não há certo ou errado. Mas deixa eu te contar uma coisa: as directives são um recurso incrivelmente útil, um que ajuda a diferenciar GraphQL de REST. Se você não as está usando, provavelmente não está aproveitando ao máximo sua API.

As directives são não regulamentadas pela spec, então os servidores GraphQL podem implementá-las da forma que quiserem, tornando-as tão poderosas quanto precisarem. É por isso que muitas funcionalidades novas no GraphQL são introduzidas primeiro por meio de directives, como @stream e @defer.

O Gato GraphQL trata as directives com reverência. Elas são executadas apenas uma vez com os dados de todas as entidades, para todos os campos nos quais são aplicadas (o que explica por que a directive @strTranslate pode buscar resultados da API do Google Translate tão rapidamente), e o próprio motor GraphQL é baseado em um pipeline de directives.

Ahhhh, mas você está com medo de disponibilizar todo esse poder para os usuários, certo? É uma preocupação válida. Mas então, você pode simplesmente remover o acesso ao endpoint único e fornecer acesso aos dados apenas por meio de persisted queries, onde você (o administrador do site) é a única pessoa com acesso às directives.

Portanto, ou você se beneficia, ou nada acontece.

Se você ama directives, ótimo, você vai adorar o Gato GraphQL! ❤️

Mas, por outro lado, se você não gosta, nada acontece.

Vencedor do round: Gato GraphQL.

(Se você acredita que "não precisamos de directives fedorentas", por favor não fique com raiva de mim... Estou apenas fazendo meu trabalho.)

Round 11: Suporte a REST

"Ahhhhh? REST? Que REST? Não estamos falando de GraphQL aqui? Por que você fala de REST então? Por que você quer complicar minha vida?"

Mais do que isso, não posso fazer por você

Sim, à primeira vista este tópico parece fora de lugar. Mas o adicionei nesta comparação por uma razão muito simples: Matt Mullenweg disse que está avaliando GraphQL para uma possível inclusão no core do WordPress, e a única coisa com que os contribuidores vão se preocupar é ter que manter duas codebases.

O que leva à pergunta óbvia: o servidor GraphQL também pode lidar com REST?

A resposta é "parcialmente sim" para o WPGraphQL, e "completamente sim" para o Gato GraphQL.

Sobre o WPGraphQL. É possível definir um endpoint REST que, quando resolvido, simplesmente executa uma query GraphQL contendo os campos necessários, seja como uma chamada interna ao motor GraphQL, seja como uma operação POST externa executada contra o mesmo servidor web.

Mas isso não é suficiente para satisfazer a WP REST API, pois ela também tem um schema JSON, e não podemos prescindir dele.

Sobre o Gato GraphQL. Devo admitir que tive sorte, pois o trabalho no seu motor subjacente (o modelo de componentes do lado do servidor chamado PoP) começou por volta de 2013, ou seja, vários anos antes de eu conhecer algo chamado GraphQL, e esse projeto evoluiu com algumas ideias próprias (que documentei neste artigo vintage meu).

Então, quando comecei a codificar o servidor GraphQL CMS-agnostic (no qual o Gato GraphQL se baseia) há cerca de 1,5 anos, mesclei as ideias desenvolvidas para o PoP com as bases estabelecidas pelo GraphQL, criando um sistema que suporta a spec GraphQL em sua totalidade, sendo capaz de adicionar um conjunto diferente de recursos a ela.

Nesse sentido, o schema que o PoP usa é API-agnostic, e é um superconjunto do GraphQL. O schema PoP está em /api/graphql/?query=fullSchema.

Então, a camada do servidor GraphQL formata o schema PoP seguindo a especificação GraphQL, o que produz o schema GraphQL. E da mesma forma, podemos produzir o schema JSON exigido pela WP REST API.

Gerar esse schema JSON ainda não foi feito, mas é viável.

O que já foi feito é produzir a resposta da query em múltiplos formatos. Por exemplo, esta query GraphQL:

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

Também é resolvida por este endpoint REST: /posts/api/rest/?query=id|title|date|author.name.

E não precisamos parar por aí. Você precisa produzir os resultados usando um formato ainda diferente, como XML? No problemo: /api/?query=posts.id|title|date|author.name&datastructure=xml.

(Isso poderia ajudar a implementar a proposta de uma nova ferramenta de importação/exportação para WordPress, baseada em um schema. Isso também torna um pouco mais evidente o que disse anteriormente: uma única interface pode alimentar todas as interações com dados, tanto dentro do CMS quanto do CMS para APIs externas.)

Vencedor do round: Gato GraphQL.

Round 12: Suporte a funcionalidades inovadoras

A spec GraphQL é definitiva? A resposta é não: a spec está em constante evolução. Neste momento, há 100 issues abertas, muitas delas contendo propostas que serão formalizadas em algum momento no futuro.

Ora, entre essas 100 issues, certamente haverá novos recursos dos quais podemos nos beneficiar hoje, certo? Se sim, por que esperar?

É exatamente esse o meu modo de pensar.

Não podemos esperar para sempre

"Mas se algo não está na spec GraphQL, então não devemos adicioná-lo ao servidor GraphQL, ou os usuários ficarão confusos!"

Boa colocação. No entanto, se tornarmos os novos recursos disponíveis apenas como opt-in, então os usuários necessariamente estarão cientes disso, e nenhum problema ou mal-entendido ocorrerá.

Mais uma vez, é esse o meu modo de pensar. No entanto, é uma questão de opinião, portanto, se você preferir usar apenas recursos que todos os servidores GraphQL existentes também estão usando, tudo bem.

Acredito que é assim que o WPGraphQL opera. Pelo menos, não vi um único recurso que vá além do que foi aprovado na spec.

Para o Gato GraphQL, porém, regularmente vasculho a lista de issues na spec e, se encontro algum recurso bacana que pode ser satisfeito pelo meu servidor sem muito esforço, então o implemento. (Na verdade, esse é um dos meus hobbies.)

Estes são os recursos "voltados para o futuro" que implementei até agora:

Execução de múltiplas queries
Namespacing de schema
Mutations aninhadas
Directives combináveis
Feedback proativo
Versionamento baseado em campos e directives

E já estou planejando adicionar:

✳️ Subscriptions (isso já faz parte da spec)
✳️ Directives @stream e @defer
✳️ Sintaxe de cadeia plana

Vencedor do round: Gato GraphQL.


Veredicto!

Senhoras, senhores.

É hora do veredicto

Que noite inesquecível tivemos! Que luta acabamos de presenciar! Dois grandes pesos-pesados dando o melhor de si pelo seu sonho.

Um sonho que ambos estão perseguindo, mas que apenas um pode alcançar.

E agora, saberemos quem é essa pessoa. Agora, é hora da verdade!

Quem será o campeão mundial de "GraphQL no WordPress"?

Será o amplamente aclamado, amado pelas massas, figurando nas grandes publicações, campeão atual, WPGraphQL?

Ou será o irreverente, pisa-no-seu-calo-sem-pedir-desculpa, chega-sem-ser-convidado-à-festa desafiante, Gato GraphQL?

Os contendores aguardam o veredicto

Estamos aguardando o veredicto do juiz. Que tensão! Oh Santa Maria, faça meu coração resistir a este momento!

🥁 E 🥁 o 🥁 vencedor 🥁 éééééééééééé 🥁 ...

É um empate!

Os 2 lutadores, os 2 pesos-pesados, empataram!

Os contendores se abraçam

Que momento maravilhoso! Os dois contendores se abraçam, mostrando que somos todos amigos dentro da comunidade WordPress, como uma grande família que somos.

Então, qual é a justificativa para o empate? O juiz explica:

👑 O WPGraphQL é o mais popular, e seu uso é mais difundido.

👑 O Gato GraphQL tem uma arquitetura melhor, e poderia potencialmente servir melhor ao WordPress no longo prazo.

Senhoras e senhores, vocês ouviram o veredicto do juiz!

E nosso troféu tem duas luvas: uma para cada contendor.

O troféu 'GraphQL no WordPress'

Mas qual é o seu veredicto?

Você vai continuar usando o WPGraphQL incondicionalmente para suas necessidades headless?

Ou vai dar ao Gato GraphQL a oportunidade que ele reivindica, baixar o plugin, e experimentá-lo?


Senhoras e senhores. É tudo por esta noite.

Esperamos sinceramente que tenham apreciado a luta.

E esperemos que em breve tenhamos um novo encontro entre nossos dois campeões.

Boa noite.

Atualização 01/05/2024: Saiba mais na comparação Gato GraphQL vs WPGraphQL.


Assine nossa newsletter

Fique por dentro de todas as atualizações do Gato GraphQL.