Blog

🥊 Gato GraphQL vs WPGraphQL: ¡el combate!

Leonardo Losoviz
Por Leonardo Losoviz ·

Actualización 01/05/2024: Echa un vistazo a la comparación Gato GraphQL vs WPGraphQL.

Señorassssssssssss, y señores.

Anunciando el próximo combate

Bienvenidos al MGM Grand Garden Arena para el combate del siglo. Esta noche, estamos haciendo historia. Dos jóvenes luchadores se enfrentarán cara a cara en el ring, chocando por el premio por el que han trabajado tan duro:

Convertirse en el campeón mundial de "GraphQL en WordPress" 🏆

A nuestra derecha, tenemos al actual campeón. Aunque solo tiene 4 años, ya está repleto de experiencia, habiendo alcanzado recientemente la versión 1.0 y publicado en el directorio de wp.org, y es muy popular entre las multitudes.

🥁 Demos 🥁 la 🥁 bienvenida 🥁 aaaaa 🥁 ...... WPGraphQL.

El actual campeón, WPGraphQL

A nuestra izquierda, tenemos al retador. Apenas ha estado fuera 1 mes, pero es muy energético y ambicioso, mostrando su fuerza desde el primer día. Ha sido él quien ha buscado el encuentro de hoy. Esta noche es su oportunidad, y el mundo está prestando atención.

🥁 Demos 🥁 la 🥁 bienvenida 🥁 aaaaa 🥁 ...... Gato GraphQL.

El retador, Gato GraphQL

Esta noche, nuestros contendientes se encontrarán cara a cara por primera vez, en un combate de 12 asaltos. Mientras toman sus posiciones en el centro del ring, esperando la campana inicial, se estudian mutuamente, intentando encontrar los puntos vulnerables del otro. Sin embargo, solo exhiben confianza.

Los 2 gloriosos luchadores se estudian mutuamente

¿Quién prevalecerá? ¿Mantendrá WPGraphQL su ventaja, basada en el apoyo de sus seguidores? ¿O convencerá el recién llegado Gato GraphQL a una comunidad desprevenida del poder de sus puños, dejando un rastro de asombro que convierte a las multitudes a su lado?

Esta noche, señoras y señores, lo descubriremos.

Haced vuestras apuestas. ¡Y disfrutad del combate!


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


Recientemente me han pedido que explique las diferencias entre mi plugin, Gato GraphQL, y WPGraphQL.

Ambos plugins son servidores GraphQL para WordPress, así que cumplen el mismo propósito. Sin embargo, bajo el capó tienen características diferentes, lo que puede hacer que uno sea mejor que el otro para satisfacer algún comportamiento requerido.

Aunque estoy sesgado hacia mi propio plugin, he intentado hacer una comparación que sea justa, basada en temas que considero importantes tanto para GraphQL como para WordPress. (Si los lectores quisieran una comparación sobre otro tema, estaré encantado de complacer.)

La comparación no es exhaustiva. Por ejemplo, también me gustaría hacer algunos benchmarks, midiendo la velocidad de resolver la misma consulta GraphQL con ambos servidores. (Si los lectores encuentran atractiva esta propuesta, puedo hacerlo en un próximo artículo.)

He dividido mi comparación en 4 áreas principales: Popularidad, Estilo de código y estándares, Asuntos urgentes, y Ampliando el alcance, con 3 elementos para cada una, dando un total de 12 "asaltos". Al final, los jueces dan su veredicto, para nombrar al campeón.

Haz clic abajo para saltar directamente a algún tema:

🔔 Ding 🔔 ding 🔔 diiiiiing...

La campana inicial ha sonado...

¡El combate ha comenzado!


Popularidad

Cualquier pieza de software (o tecnología, para el caso) debe ser usada por personas, o de lo contrario el ser mejor que las alternativas será solo una anécdota.

Por ejemplo, aunque existen alternativas que permiten escribir más rápido, seguimos usando mayoritariamente el teclado QWERTY.

¿Cómo de populares son los dos plugins?

Asalto 1: Quién lo está usando, y cuán completo es

WPGraphQL ha sido, hasta ahora, sinónimo de GraphQL en WordPress. Durante los más de 4 años que se ha desarrollado (empezando en noviembre de 2016), ha reunido más de 2,8 mil estrellas en el repo, una comunidad de más de 4600 seguidores, y casi 100 contribuidores al proyecto.

Alcanzó la versión 1.0 y se subió al directorio de plugins en wp.org en noviembre de 2020. Desde entonces, ha reunido más de 8000 instalaciones activas. Actualmente es la única solución para obtener contenido de WordPress en Gatsby y, más recientemente, varios proyectos lo han añadido a sus stacks, incluyendo el framework Headless de WPEngine y el starter de WordPress con Next.js de WebDevStudios.

En otras palabras, WPGraphQL es popular.

El desarrollo de Gato GraphQL empezó en serio hace alrededor de 1,5 años (como parte de un proyecto más amplio), y alcanzó un estado "suficientemente bueno" hace 6 meses, recibiendo 150 estrellas en el repo desde entonces. El plugin está actualmente en la versión 0.7, y todavía está a varios meses de alcanzar la 1.0 (por ejemplo, todavía no tiene categorías en el esquema).

El mes pasado lancé este sitio actual gatographql.com, y desde entonces he estado promocionando el plugin vía el blog (como el artículo que estás leyendo ahora), y también publiqué un artículo introductorio en CSS-Tricks. Estos intentos han traído a varios cientos de personas al sitio, y más de 100 visitantes han descargado el plugin.

En otras palabras, Gato GraphQL se está haciendo popular lentamente pero de forma constante, y es un trabajo en progreso.

Ganador del asalto: WPGraphQL.

¡Es un golpe! El puñetazo de WPGraphQL alcanza a Gato GraphQL

Asalto 2: Disponibilidad de extensiones

Las extensiones permiten interactuar con otros plugins a través de Gato GraphQL.

WPGraphQL tiene extensiones para ACF, WooCommerce, Yoast y algunas otras.

Gato GraphQL todavía no tiene extensiones, y no espero que haya muchas antes de lanzar la versión 1.0.

Sin embargo, Gato GraphQL pone un gran énfasis en las extensiones en su arquitectura, permitiendo al usuario gestionarlas (habilitarlas, deshabilitarlas, configurarlas, y leer su documentación) desde un lugar central, la página "Modules":

Página de Modules en Gato GraphQL

En otras palabras, mientras WPGraphQL ya tiene extensiones, Gato GraphQL está preparando el terreno para ellas.

Ganador del asalto: WPGraphQL.

¡WPGraphQL golpea de nuevo!

Asalto 3: Audiencia objetivo

WPGraphQL se dirige a desarrolladores: si quieres extraer datos de tu sitio WordPress, necesitas almacenar tu consulta GraphQL en algún lugar de tu código (lo más probable, en alguna función JavaScript). Luego, para poder usarla, necesitas ser lo suficientemente bueno programando.

Gato GraphQL, en cambio, sigue la filosofía de WordPress de que cualquiera debe poder usarlo, incluyendo los no técnicos. Para lograr este objetivo, permite crear y gestionar una consulta GraphQL vía el editor de WordPress, de manera que hacer los datos del sitio WordPress accesibles vía API se vuelve tan fácil como crear una entrada de blog.

Además, Gato GraphQL pone más énfasis en ofrecer clientes para interactuar con el servicio GraphQL de manera visual. Mientras que ambos plugins proporcionan el cliente GraphiQL, para ejecutar la consulta, solo Gato GraphQL también proporciona el cliente Voyager, para explorar interactivamente el esquema:

Visualizando el esquema GraphQL

Ganador del asalto: Gato GraphQL.

¡Gato GraphQL asesta un buen golpe de izquierda!


Estilo de código y estándares

¡Hablemos de código!

Si estás usando GraphQL, lo más probable es que estés haciendo WordPress headless y renderizando el sitio web usando algún framework JavaScript, lo cual es un paradigma moderno. Además, WordPress puede ser un CMS antiguo, pero GraphQL es una interfaz moderna para acceder a datos del sitio. Por lo tanto, puedo asumir con seguridad que eres un desarrollador sabio, deseoso de producir código elegante, y no aceptará usar una solución subóptima.

¿Qué tan elegante es el código (de su propio codebase, y esperado de nuestras implementaciones personalizadas) de estos dos plugins?

Asalto 4: Requisitos de PHP

Tanto WPGraphQL como Gato GraphQL requieren PHP 7.1+.

Sin embargo, hay una diferencia: Gato GraphQL en realidad está codificado usando PHP 7.4, y luego es transpilado a PHP 7.1 para producción.

Por lo tanto, programar Gato GraphQL es mucho más placentero: puedes usar características más nuevas de PHP, incluyendo el tipo object, propiedades tipadas y arrow functions. Y una vez añadido el soporte para PHP 8.0 (que ocurrirá cuando se lance la nueva versión de Lando), también podrás usar union types, la expresión match, y otros.

Ganador del asalto: Gato GraphQL.

¡Gato GraphQL está dejando su huella!

Asalto 5: Prácticas de codificación

Empecemos con WPGraphQL. Dirigiéndonos al repo wp-graphql/wp-graphql, hay algo que destaca para mí:

La carpeta vendor almacenada en el repo

Haciendo zoom:

Contenidos de la carpeta vendor

Lo siento, pero solo hay una manera en que puedo reaccionar ante esto:

Te puedo perdonar muchas cosas en la vida, pero no esto

Hacer commit de la carpeta vendor de Composer al repo es una mala práctica, y Composer lo desaconseja explícitamente.

Solucionar este problema no es difícil (incluso describí una manera basada en GitHub actions), así que me pregunto por qué está ahí.

Diría que, en este asalto, ¡WPGraphQL se está golpeando a sí mismo!

¡Ay!

Continuemos. Desarrollar para WPGraphQL requiere conocer una colección súper extensa de hooks (actions y filters). Yendo a la Developer reference de WPGraphQL, podemos apreciar el alcance de esto.

Para hacer una captura de la lista de actions, tuve que reducir el zoom de mi navegador al 50 %:

Action hooks para extender WPGraphQL

Para la lista de filters, reduje al 30 % (el mínimo que Firefox soporta), e incluso así no pude obtener toda la lista:

Filter hooks para extender WPGraphQL


Cambiemos al repo GatoGraphQL/GatoGraphQL, que es el monorepo que contiene Gato GraphQL (entre otros proyectos).

Estas son algunas de las características del código:

✅ Cumple con los estándares PSR-1, PSR-4 y PSR-12.

✅ Todo el código se divide en múltiples paquetes atómicos, y todos ellos (más de 100 para el plugin, más de 200 para todo el proyecto) están alojados en el mismo monorepo.

✅ Usa Composer para gestionar todas las dependencias.

✅ Usa Symfony Dependency Injection para gestionar todos los servicios en la aplicación. Para registrar un nuevo type resolver, field resolver o directive resolver, solo tenemos que registrar un nuevo servicio en el contenedor.

✅ Cada clase es un servicio, y Symfony Dependency Injection se encarga de hacer el autowiring de toda la aplicación.

✅ El servidor GraphQL subyacente es CMS-agnostic. Gato GraphQL implementa los contratos para WordPress, y añade un poco de lógica personalizada (por ejemplo, para proporcionar los clientes).

El código específico de WordPress es solo alrededor del 10 % del código total. Replicar este 10 % para otro framework o CMS (Laravel/Drupal/etc) puede proporcionar una implementación de un servidor GraphQL para ellos también.

✅ Como consecuencia de ser CMS-agnostic, programar un resolver implica codificar su lógica de negocio genérica, potenciada por servicios reutilizables. Nunca pensamos en términos de código WordPress, y rara vez necesitamos lidiar con su deuda técnica.

✅ Asimismo, el esquema GraphQL no es una réplica 1:1 del modelo de datos de WordPress, evitando la deuda técnica acumulada por WordPress en la capa de datos, y proporcionando una interfaz limpia.

✅ El problema N+1 de GraphQL no puede ocurrir, por diseño arquitectónico, y sin molestar al desarrollador en absoluto.

✅ El servidor no es solo un servidor GraphQL: es en realidad un servidor de API, donde la respuesta puede ser emitida en otros formatos o especificaciones (ej: REST) desde una única fuente de verdad. (Más sobre esto en el asalto 11).

✅ No se hace commit del directorio vendor. En su lugar, el código fuente se transforma en código de distribución (es decir, el plugin final para instalar en el sitio WordPress) vía GitHub actions, y se despliega a un repo dist, donde sí contiene la carpeta vendor.

✅ Al generar el código para distribución, se le hace scoping con PHP-Scoper, y el código fuente, que contiene código PHP 7.4, se transpila a PHP 7.1.

✅ Como ha resuelto el scoping, el plugin puede basarse en cualquier dependencia de terceros. Actualmente, hace uso de DependencyInjection de Symfony, Cache y Dotenv, Guzzle (para interactuar con APIs externas), Pipeline de The League, y varios otros.

Esto es importante no solo para el presente, sino también para el futuro: puedo tener la certeza de que puedo usar cualquier dependencia del repositorio Packagist, así que no necesito reinventar la rueda.

Los campos están suscritos a tipos, haciendo el esquema GraphQL fácil de extender.

Ganador del asalto: Gato GraphQL (por un amplio margen, me atrevo a decir, si no te importa).

Tras un asalto duro, WPGraphQL necesita algo de descanso

Asalto 6: Extender el esquema

Añadamos un campo al esquema GraphQL.

Seguimos el tutorial para WPGraphQL. El código sugerido es el de abajo. Declara un action hook para ejecutar una función que declara un array. Tanto la descripción de los campos, como su resolución, se proporciona dentro del 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 ejemplo es tan simple como puede ser: el resolver básicamente no hace nada. Sin embargo, ya tengo problemas para mirar el código y entender de una vez qué hace. No, no estoy siendo sarcástico: todos los colores de ese código en mi editor luchan por mi atención. Además, no hay separación de responsabilidades, y el código no parece ser muy reutilizable.

Por lo tanto, dependerá del desarrollador (es decir, de ti) hacer el código fácil de leer, reutilizable, sin bugs, y muchas otras cosas, mientras desarrolla la aplicación; la librería en sí no parece ayudar mucho en este aspecto.

A este estilo lo llamo "ADD": Array-Driven Development. No puedo decir que sea un fan.

(Para ser justos con WPGraphQL, esta es una práctica de codificación estándar, y es también la empleada por el motor subyacente webonyx/graphql-php.)


En Gato GraphQL, todo el código es SOLID. Para registrar un campo en el esquema GraphQL, creamos una clase que implementa la interfaz FieldResolverInterface (en realidad, extendiendo de AbstractSchemaFieldResolver, que tiene muchos métodos ya implementados), y la registramos en el contenedor.

Por ejemplo, este código proporciona los campos username, email y 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;
  }
}

Creo que mi solución es más elegante que la de WPGraphQL. Sin embargo, eso es cuestión de gusto. Sé que a muchos desarrolladores no les molesta el Array-Driven Development, y de hecho lo prefieren ya que, en un blob compacto de código, pueden implementar toda la lógica.

Ganador del asalto: empate.

Un empate


Descanso

Qué noche tenemos, señoras y señores.

Hora de analizar el combate hasta ahora

Hemos alcanzado la mitad del combate, así que este es un buen momento para una pausa al baño, y hacer algún comentario sobre lo que hemos experimentado hasta ahora.

(Mientras tanto, debería mostrar un anuncio de mis patrocinadores. Desafortunadamente, todavía no tengo ninguno. Si te gustaría que tu empresa financiara el desarrollo de Gato GraphQL, y obtuviera exposición en medios de primer nivel como este evento, envíame un mensaje.)

Patrocíname, para acceder a publicidad de primer nivel para tu marca

¡Qué combate tenemos! ¡WPGraphQL fue inicialmente puro fuego y furia! Empezó el combate en gran forma, dando golpes terriblemente poderosos a Gato GraphQL, quien apenas podía mantenerse en pie. Golpe tras golpe tras golpe. No me hubiera gustado estar en los zapatos de Gato GraphQL.

Debo admitir, pensé que tras los primeros 2 asaltos, el combate pronto terminaría. Esperaba que el knock-down llegara en cualquier momento. Ver una toalla ondear pidiendo misericordia. Pero Gato GraphQL resistió. Tenemos que reconocérselo. ¡Qué determinación inquebrantable, es verdaderamente extraordinario!

Y entonces, ocurrió la transformación. Empezando en algún punto del 3er asalto, Gato GraphQL pareció sacar energías de la nada, y empezó no solo a defenderse, sino a devolver puñetazos, muchos de los cuales aterrizaron en la cara de WPGraphQL. ¡Vi a WPGraphQL temblar y agitarse! Nunca habíamos visto nada así de nuestro actual campeón mundial. ¡Qué transformación verdaderamente extraordinaria acabamos de experimentar!

Y entonces, teniendo la confianza de su oponente sacudida, empezando en el 4º asalto Gato GraphQL se encargó de asestar una serie de golpes letales. ¡Eso fue asombroso! Por suerte, enfrentándose a él está nuestro campeón mundial, WPGraphQL, y pudo soportar los golpes, animado por los vítores y la compasión de las multitudes. ¡Qué héroe es! Cualquier otro habría sucumbido al instante, pero él no, soportó los golpes como el campeón que es.

Pero campeón, ¿lo será por mucho más tiempo? Nadie ha sido noqueado todavía, nadie ha tirado la toalla todavía. La pelea podría en cualquier momento dar un giro decisivo. Los dos luchadores saben lo que quieren, y estoy seguro de que volverán a salir con todo su poder, y toda su determinación, para arremeter contra su oponente, para prevalecer.

¡Qué combate tenemos!

Y ahora, señoras y señores, los dos guerreros vuelven al ring.

Los contendientes vuelven al ring

¡A por el resto del combate!


Asuntos urgentes

El servidor GraphQL necesita prestar atención a muchas consideraciones, solo para satisfacer la propuesta "obtener los datos que necesitas, ni más ni menos".

Por ejemplo:

  • ¿Cuán seguro es? ¿Cómo nos aseguramos de no exponer datos privados en un endpoint público?
  • ¿Cuán performant es? ¿Cómo podemos reducir la carga en el servidor al enviar una y otra vez la misma consulta, haciéndola lo más rápida posible?
  • ¿Cuán simple es? ¿Cuán bien integrado está con WordPress, como para aprovechar las características proporcionadas por el CMS?

Y muchas más preguntas. Esta es solo una pequeña muestra que he elegido, y que abordaré en los siguientes 3 asaltos.

Asalto 7: Persisted queries

Las persisted queries combinan lo mejor tanto de GraphQL como de REST: se crean usando GraphQL, así que no hay under/over fetching de datos, pero se publican en el servidor como un endpoint, con su propia URL.

Las persisted queries proporcionan estos beneficios:

✅ Es seguro: en lugar de dar acceso a cualquier dato a través del único endpoint, podemos pre-definir qué datos exponer.

✅ Es rápido: al acceder vía su propia URL, puede ser cacheada en cada capa entre el cliente y los back-ends (en el servidor, CDN, navegador) usando el HTTP caching estándar.

WPGraphQL ofrece soporte para persisted queries a través de estas dos extensiones:

Además, Jason Bahl (creador de WPGraphQL) anunció recientemente que en un futuro próximo añadirá soporte para persisted queries en WPGraphQL.

Me pregunto qué tiene en mente, ya que ya hay 2 extensiones. ¿En qué se diferenciará de aquellas? ¿Quizás quiere hacerlo parte del core del plugin, como para reforzar las medidas generales de seguridad del plugin sin depender de un tercero?

¿O quizás vio la implementación de Gato GraphQL, y quiere proporcionar una experiencia similar, operándolo vía un editor visual en lugar de código puro?

Lo que nos lleva a Gato GraphQL. No solo ofrece persisted queries, sino que se ha esforzado en hacerlo una parte central de la oferta:

✅ El plugin permite deshabilitar el único endpoint, y se anima a los usuarios a exponer datos solo vía persisted queries.

(En cambio, WPGraphQL solo deshabilita la introspección por defecto, no el endpoint en sí. En otras palabras, los atacantes pueden seguir siendo capaces de acceder a datos privados; solo se les hace su tarea más difícil, ya que no sabrán de antemano qué datos privados hay.)

✅ Está profundamente integrado con el editor de WordPress, así que crear una persisted query toma el mismo esfuerzo que crear una entrada de blog, y cualquiera puede hacerlo, no solo los programadores.

✅ Las persisted queries no son estáticas: pueden usar variables GraphQL, cuyo valor puede proporcionarse a través de parámetros URL al ejecutar el endpoint.

Echa un vistazo a la experiencia de crear y ejecutar una persisted query en mi plugin:

Ganador del asalto: Gato GraphQL.

Asalto 8: Caché

GraphQL tiene un gran punto débil: no es fácilmente cacheable. La razón es que depende de enviar operaciones POST a un único endpoint. Como el único endpoint producirá resultados diferentes, y como la consulta se envía en el cuerpo de la solicitud en lugar de en parámetros URL, entonces no podemos tener el único endpoint cacheado.

La solución estándar ofrecida por muchos servidores GraphQL es trasladar el caching al cliente, y basarse en los IDs de los objetos como identificadores de la entidad a cachear en lugar de en la URL del endpoint. La librería más popular que proporciona esta funcionalidad es el cliente Apollo.

Hay una discusión en el repo de WPGraphQL sobre todas las opciones disponibles para el caching de WPGraphQL. Curiosamente, la mayoría de ellas son herramientas externas (como el cliente Apollo, o el WordPress Object Cache), lo que significa añadir una capa extra a la aplicación, aumentando su complejidad, y también posiblemente haciéndola más lenta.

(Estas razones deben estar parcialmente detrás de la decisión de implementar persisted queries nativamente en WPGraphQL.)

Por ejemplo, el cliente Apollo se ejecuta, bueno, en el cliente. Si se accede al sitio web desde un teléfono móvil de gama baja, sin mucha potencia, ese código JavaScript extra tendrá un impacto en el rendimiento de la aplicación.

Asimismo, los desarrolladores que trabajan con WordPress pueden ser hábiles con PHP, pero no tanto con JavaScript. Ahora, cachear sus APIs significará que necesitan preocuparse por la capa JavaScript también.

Gato GraphQL ha sido más inteligente sobre este tema. Como proporciona persisted queries, lo que significa que las consultas se ejecutan en su propio endpoint, permite cachear estas URLs de endpoint vía HTTP caching.

La cabecera de HTTP caching tiene el valor max-age calculado automáticamente desde todos los valores max-age para todos los campos en la consulta, y esta información se configura usando el editor de WordPress, campo por campo.

Como consecuencia, la API puede ser cacheada a través de varias capas (en el cliente, CDN, y servidor), y se gestiona nativamente dentro del plugin, sin la necesidad de añadir otra capa.

Echa un vistazo a este vídeo mostrando cómo los endpoints API están siendo cacheados:

Ganador del asalto: Gato GraphQL.

Asalto 9: Integración con Gutenberg

Solía ser que Gutenberg sería el futuro de WordPress. Ya no: Gutenberg es ahora el presente de WordPress (así que podemos referirnos a él como el editor de WordPress), y Full Site Editing se ha convertido en el nuevo futuro.

No hace falta decir que nuestras APIs necesitan tener una buena integración con el editor de WordPress. Esto significa no solo para obtener y publicar datos para bloques, sino también para potencialmente potenciar características en el propio editor de WordPress.

Por ejemplo, como las subscripciones GraphQL pueden hacer que el servidor envíe datos al cliente en tiempo real, sería adecuado para potenciar las características de edición colaborativa y notificaciones.

WPGraphQL puede consultar datos de bloques vía la extensión WPGraphQL Gutenberg. Esta extensión crea un nuevo tipo para mapear cada bloque, así que tenemos CoreParagraphBlock, CoreQuoteBlock, etc.

Gato GraphQL pronto podrá consultar datos de bloques (es un trabajo en progreso). Sin embargo, en lugar de crear un nuevo tipo por bloque, tendrá un único tipo Block para representar todos los bloques, y luego podemos extraer los metadatos específicos para algún bloque basado en su nombre.

Por ejemplo, mira cómo puedes traducir el contenido dentro de un bloque párrafo (usando la directiva @strTranslate, que se conecta a la API de 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")
  }
}

Ganador del asalto: empate.


Ampliando el alcance

"Tengo un sueño."

Los bloques de Gutenberg han sido concebidos para proporcionar una única interfaz para crear contenido en WordPress, simplificando enormemente el desarrollo del código para el CMS, y el aprendizaje requerido de los usuarios.

Aunque introducidos para crear contenido, los bloques están tomando constantemente todas las demás áreas del CMS, incluyendo widgets, menús y, próximamente, themes vía Full Site Editing. Y en el futuro, también soportarán capacidades multilingües y edición colaborativa (características en las que podríamos ni siquiera pensar al pensar en bloques), y quién sabe qué más.

Podemos pensar en GraphQL en los mismos términos: como una única interfaz para interactuar con datos. Eso significa, no solo fetch y post de datos, sino cualquier interacción que involucre datos, incluyendo la edición.

WordPress tiene una oportunidad única de convertirse verdaderamente en el SO de la web: un sistema potenciado por Gutenberg, que permite al usuario introducir cualquier tipo de contenido (texto, imágenes, vídeo, audio, etc), procesarlo vía sus propias herramientas o algún servicio basado en la nube, y publicarlo en su destino final, ya sea el sitio WordPress o en algún otro lugar.

Pero detrás de este poderoso sueño, debe haber una API verdaderamente poderosa, para entregar cualquier requisito que le pongamos. Una API que podría basarse en GraphQL, pero que fue diseñada para también trascender sus limitaciones.

Asalto 10: Soporte para directivas personalizadas

Inicio del asalto 10

WPGraphQL no viene con una sola directiva. No digo que no las soporte (su motor webonyx/graphql-php sí lo hace), sino que no ofrece una implementación de ninguna directiva personalizada.

"¿Y qué?" podrías pensar. "¿Para qué necesitamos directivas? Si alguien necesita modificar el resultado de la consulta, puede hacerlo en su propio cliente."

¿Por qué necesito directivas?

Esto es cuestión de opinión, y no hay un correcto o incorrecto. Pero déjame decirte algo: las directivas son una característica increíblemente útil, una que ayuda a distinguir a GraphQL de REST. Si no las estás usando, lo más probable es que no estés sacando el máximo provecho de tu API.

Las directivas están no reguladas por la spec, así que los servidores GraphQL pueden implementarlas como quieran, hacerlas tan poderosas como necesiten. Por eso muchas nuevas funcionalidades en GraphQL se introducen primero vía directivas, como @stream y @defer.

Gato GraphQL trata las directivas con reverencia. Se ejecutan solo una vez con los datos de todas las entidades, para todos los campos a los que se aplican (lo que explica por qué la directiva @strTranslate puede obtener resultados de la API de Google Translate tan rápidamente), y el propio motor GraphQL se basa en un pipeline de directivas.

Ahhhh, ¿pero tienes miedo de hacer todo este poder disponible para los usuarios, ¿verdad? Esa es una preocupación válida. Pero entonces, puedes simplemente eliminar el acceso al único endpoint, y proporcionar acceso a datos solo a través de persisted queries, donde tú (el admin del sitio) eres la única persona con acceso a las directivas.

Así que o te beneficias, o no pasa nada.

Si amas las directivas, genial, ¡amarás Gato GraphQL! ❤️

Pero, por otro lado, si no te gusta, no pasa nada.

Ganador del asalto: Gato GraphQL.

(Si crees que "no necesitamos directivas apestosas", por favor no te enfades conmigo... Solo estoy haciendo mi trabajo.)

Asalto 11: Soporte para REST

"Ahhhhh? ¿REST? ¿Qué REST? ¿No estamos hablando de GraphQL aquí? ¿Por qué hablas de REST entonces? ¿Por qué quieres complicarme la vida?"

Más que esto, no puedo hacer por ti

Sí, a primera vista este tema parece fuera de lugar. Pero lo he añadido en esta comparación por una razón muy simple: Matt Mullenweg ha dicho que está mirando GraphQL para una potencial inclusión en el core de WordPress, y lo único que preocupará a los contribuidores es tener que mantener dos codebases.

Lo que lleva a la pregunta obvia: ¿puede el servidor GraphQL también manejar REST?

La respuesta es "parcialmente sí" para WPGraphQL, y "completamente sí" para Gato GraphQL.

Sobre WPGraphQL. Es posible definir un endpoint REST que, al resolverse, simplemente ejecuta una consulta GraphQL conteniendo los campos requeridos, ya sea como una llamada interna al motor GraphQL, o como una operación POST externa ejecutada contra el mismo webserver.

Pero eso no es suficiente para satisfacer la WP REST API, porque también tiene un esquema JSON, y no podemos prescindir de él.

Sobre Gato GraphQL. Debo admitir que he tenido suerte, porque el trabajo en su motor subyacente (el modelo de componentes del lado del servidor llamado PoP) comenzó alrededor de 2013, es decir varios años antes de que yo supiera de algo llamado GraphQL, y este proyecto evolucionó con algunas ideas propias (que documenté en este artículo vintage mío).

Entonces, cuando empecé a programar el servidor GraphQL CMS-agnostic (sobre el cual se sostiene Gato GraphQL) hace alrededor de 1,5 años, fusioné las ideas desarrolladas para PoP, con las bases establecidas por GraphQL, creando un sistema que soporta la spec de GraphQL en su totalidad, mientras puede añadirle un conjunto diferente de características.

En este sentido, el esquema que PoP usa es API-agnostic, y es un superconjunto del de GraphQL. El esquema de PoP está bajo /api/graphql/?query=fullSchema.

Entonces, la capa del servidor GraphQL formatea el esquema de PoP siguiendo la especificación GraphQL, lo que produce el esquema GraphQL. Y de manera similar, podemos producir el esquema JSON requerido por la WP REST API.

Generar este esquema JSON todavía no se ha hecho, pero es factible.

Ahora, lo que ya se ha hecho, es producir la respuesta de la consulta en múltiples formatos. Por ejemplo, esta consulta GraphQL:

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

También se resuelve vía este endpoint REST: /posts/api/rest/?query=id|title|date|author.name.

Y no necesitamos parar ahí. ¿Necesitas producir los resultados usando un formato diferente, como XML? No problemo: /api/?query=posts.id|title|date|author.name&datastructure=xml.

(Esto podría ayudar a implementar la propuesta para una nueva herramienta de import/export para WordPress, basada en un esquema. Esto también hace un poco más evidente lo que dije antes: una única interfaz puede potenciar todas las interacciones de datos, tanto dentro del CMS, como también desde el CMS con APIs externas.)

Ganador del asalto: Gato GraphQL.

Asalto 12: Soporte para nuevas funcionalidades

¿Es la spec de GraphQL final? La respuesta es no: la spec está en constante evolución. En este momento, hay 100 issues abiertos, muchos de los cuales contienen propuestas que se formalizarán en algún momento en el futuro.

Ahora, entre esos 100 issues, ciertamente habrá nuevas funcionalidades de las que podemos beneficiarnos hoy, ¿verdad? Si es así, ¿por qué esperar?

Esa es exactamente mi forma de pensar.

No podemos esperar para siempre

"Pero si algo no está en la spec de GraphQL, ¡entonces no debemos añadirlo al servidor GraphQL, o los usuarios se confundirán!"

Buen punto. Sin embargo, si hacemos las nuevas funcionalidades disponibles solo como opt-in, entonces los usuarios necesariamente serán conscientes de ello, y no ocurrirá ningún issue o malentendido.

Una vez más, esa es mi forma de pensar. Esto es cuestión de opinión, así que si prefieres usar solo funcionalidades que todos los servidores GraphQL ahí fuera también están usando, está bien.

Creo que así opera WPGraphQL. Al menos, no he visto una sola funcionalidad que vaya más allá de lo que se ha aprobado en la spec.

Para Gato GraphQL, sin embargo, regularmente escaneo la lista de issues en la spec y, si encuentro alguna funcionalidad chula, que puede ser satisfecha por mi servidor sin mucho esfuerzo, entonces la implemento. (De hecho, este es uno de mis hobbies.)

Estas son las funcionalidades "con visión de futuro" que he implementado hasta la fecha:

Ejecución de múltiples consultas
Funcionalidades personalizadas para el esquema
Mutaciones anidadas
Funcionalidades personalizadas para el esquema
Funcionalidades personalizadas para el esquema
Funcionalidades personalizadas para el esquema

Y ya estoy planeando añadir:

✳️ Subscriptions (esto ya es parte de la spec)
✳️ Directivas @stream y @defer
✳️ Flat chain syntax

Ganador del asalto: Gato GraphQL.


¡Veredicto!

Señoras, señores.

Es hora del veredicto

¡Qué noche inolvidable hemos tenido! ¡Qué combate acabamos de experimentar! Dos pesos pesados dando lo mejor de sí mismos por su sueño.

Un sueño que ambos persiguen, pero solo uno puede atrapar.

Y ahora, sabremos quién es esa persona. ¡Ahora, es hora de la verdad!

¿Quién será el campeón mundial de "GraphQL en WordPress"?

¿Va a ser el ampliamente aclamado, amado-por-las-masas, destacado-en-grandes-publicaciones campeón actual, WPGraphQL?

¿O va a ser el irreverente, pisa-tus-pies-sin-pedir-perdón, llega-sin-invitación-a-la-fiesta retador, Gato GraphQL?

Los contendientes esperan el veredicto

Estamos esperando el veredicto del juez. ¡Qué tensión! ¡Oh Santa María, haz que mi corazón resista este momento!

🥁 Y 🥁 el 🥁 ganador 🥁 essssssssssssssssss 🥁 ...

¡Es un empate!

Los 2 luchadores, los 2 pesos pesados, ¡tienen un empate!

Los contendientes se abrazan

¡Qué maravilloso momento! Los dos contendientes se abrazan, mostrando que todos somos amigos dentro de la comunidad WordPress, como una gran familia que somos.

Entonces, ¿cuál es la justificación para el empate? El juez explica:

👑 WPGraphQL es el más popular, y su uso está más extendido.

👑 Gato GraphQL tiene una mejor arquitectura, y podría potencialmente servir mejor a WordPress a largo plazo.

¡Señoras y señores, han tenido el veredicto del juez!

Y nuestro trofeo tiene dos guantes: uno para cada contendiente.

El trofeo de 'GraphQL en WordPress'

¿Pero cuál es tu veredicto?

¿Seguirás usando incondicionalmente WPGraphQL para tus necesidades headless?

¿O le darás a Gato GraphQL la oportunidad que está reclamando, descargarás el plugin, y le darás una oportunidad?


Señoras y señores. Esto es todo por la noche.

Esperamos sinceramente que hayan disfrutado del combate.

Y esperemos que tengamos un nuevo encuentro pronto entre nuestros dos campeones.

Buenas noches.

Actualización 01/05/2024: Aprende más en la comparación Gato GraphQL vs WPGraphQL.


Suscríbete a nuestra newsletter

Mantente al tanto de todas las novedades de Gato GraphQL.