Estamos en 2020. Su equipo se inclina cada vez más hacia la creación de aplicaciones de una sola página, o al menos hacia la inclusión de componentes enriquecidos dentro de aplicaciones multipágina normales. [GraphQL](https://graphql.org/) ya tiene [más de dos años](https://en.wikipedia.org/wiki/GraphQL), lo que por JavaScript podrían considerarse maduros. Nos sentíamos un poco aventureros, así que renunciamos a las habituales API JSON y nos metimos de lleno en el tema: esto es lo que aprendimos.
Necesita un servidor GraphQL
En la mayoría de los marcos utilizados para desarrollo weblas herramientas para construir una API JSON ya están ahí. Puedes construir una estructura de rutas y aceptar fácilmente algunos GETs y POSTs, y luego dar salida a una respuesta JSON. Ruby on Rails tiene incluso una proyecto que prescinde de las bondades habituales del renderizado HTML y coloca en su lugar una base sólida de API. Lo que sigue es que un desarrollador experto que utilice herramientas modernas puede montar un backend en cuestión de minutos.
No ocurre lo mismo con GraphQL. Aunque existen bibliotecas de servidor para muchos idiomasSin embargo, se incurre en una penalización de velocidad desde el principio, simplemente por tener que averiguar qué es lo correcto para su ecosistema. Desde un punto de vista más personal, tampoco me gusta que se utilice el término "servidor" para describir una biblioteca que puede introducirse en un proyecto.
Sólo hay un punto final
A lo largo de los años nos acostumbramos a una forma particular de pensar sobre la estructura de las API. En el nivel más básico, simplemente seguíamos las prácticas REST. Eso significaba crear varios puntos finales por modelo lógico en nuestra aplicación. Es una estructura fácil de entender tanto para los autores como para los consumidores de la API. También produce métodos bien delimitados en el backend, lo que hace que el razonamiento sobre la API sea más sencillo. código tan fácil como sobre la propia API. Esta estructura también es fácil de nombrar, por ejemplo, a efectos de Versiones de la API.
GraphQL sólo emplea un único punto final, comúnmente /graphql
. Cada solicitud a su API llegará como una solicitud POST a ese punto final, y a partir de ahí es responsabilidad del servidor GraphQL averiguar lo que el cliente quiere y responder adecuadamente.
A primera vista, parece difícil de manejar: ¡imagínese intentar hacerlo todo en una API JSON con un único punto final! Sin embargo, pronto empieza a tener sentido a medida que tu API madura y algunas cosas son sustituidas por otras. La desaprobación en las API clásicas suele hacerse a nivel de espacio de nombres, pasando de v1
a v2
. GraphQL permite mucho más control, hasta la eliminación de un solo campo. Imagínese poder decirle a un consumidor de la API REST que no quiere que utilice el campo nombre
y utilizar nombre_lindo
en su lugar. Resulta que lo que parecía difícil de manejar al principio es en realidad una de las mejores características.
Todo está mecanografiado
JSON no tiene mucho en cuanto a tipificación. Hay cadenas, números, matrices y objetos. Más allá de eso, no tienes suerte. Por el contrario en GraphQL, todo comienza y termina con tipos, ya que incluso la raíz Query y Mutation son sólo eso - tipos. El DSL GraphQL impone la comprobación de tipos tanto en el servidor como en el cliente, evitando todo tipo de sorpresas desagradables.
Esto es muy importante, sobre todo porque cada vez se comprueban más los SPA, ya sea mediante TypeScript o alternativas como Flow. GraphQL facilita la introducción de tipos complejos y compuestos sobre los valores predeterminados y se convierte rápidamente en una segunda naturaleza para los desarrolladores tanto en el backend como en el frontend.
Más información: Probando el JavaScript... ¡¿con Ruby?!
Los documentos están integrados
En una API JSON clásica, la documentación puede ser una ocurrencia tardía. E incluso si no lo es, hay muchos métodos entre los que elegir. ¿Usamos algún esquema como OpenAPI? ¿Lo convertimos entonces a un formato legible por humanos con herramientas como Swagger? ¿O simplemente volcamos un montón de archivos Markdown en algún sitio? Aunque este problema se ha resuelto en múltiples ocasiones, sigue requiriendo una reflexión y un esfuerzo conscientes por parte del equipo: primero para crear los documentos y luego para mantenerlos actualizados y difundirlos. Es un problema aún más complejo cuando la API tiene varias secciones a las que sólo pueden acceder, por ejemplo, determinados roles de usuario.
En GraphQL la documentación es un ciudadano de primera clase ya que la mayoría de servidores permiten documentar sus tipos y peticiones in situ. Desde principios de 2018 el GraphQL Schema Definition Language forma parte de la especificación oficial, por lo que existe precisamente una forma de documentar una API GraphQL. Además como GraphQL permite definir la visibilidad de ciertas partes del grafo, automáticamente se evita que aquellos usuarios que no deban vean docs de aquello a lo que no pueden acceder. Tener la decisión tomada y unas directrices claras ha sido una gran ayuda para el equipo.
Sólo hay dos tipos de acción
A diferencia de GET, POST, PUT, PATCH y DELETE de HTTP, en GraphQL sólo hay dos tipos de acciones: Consultas y Mutaciones. La principal diferencia es que las Mutaciones pueden y alterarán el estado del sistema y las Consultas sólo leerán datos pasivamente.
Admito que todavía estoy indeciso. Me gusta la plétora de verbos HTTP para interactuar con los recursos y ser capaz de utilizar la herramienta adecuada para el trabajo. GraphQL hace que sea más fácil ocuparse de esos casos peliagudos en los que cualquiera de los verbos HTTP no se ajusta exactamente, pero incurre en la penalización de tener que pensar en lo que una mutación particular afectará realmente. También se puede decir que, dado que no hay una convención de nomenclatura estándar incorporada, tendrás que elaborar guías de estilo internas o arriesgarte a crear un lío incoherente.
Necesitas un cliente
Interactuar con las API REST a través de HTTP es muy fácil en JavaScript vainilla, y aún más utilizando el moderno módulo buscar
API. En cambio, para GraphQL es necesario utilizar una biblioteca cliente si se desea un rendimiento realmente decente. No es imposible interactuar con una API GraphQL utilizando sólo JavaScript vainilla - es sólo peticiones POST después de todo. Sin embargo, el uso de tecnologías Web de larga data como el almacenamiento en caché de solicitudes para las llamadas comunes a la API no funcionará, ya que las solicitudes POST generalmente no se almacenan en caché.
Cada cliente GraphQL razonable implementa un mecanismo de caché de resultados del lado del cliente, y muchas más características. Gracias a todas estas opciones hacer a mano una configuración para un cliente GraphQL a nivel de entrada es una tarea completamente estupefaciente. Cuando se empieza con GraphQL recomiendo especialmente echar un vistazo a Apollo-Boost ya que viene con valores por defecto muy razonables.
El cliente elige los datos
A todos nos ha pasado: sacamos una lista de datos de la API y le falta algún campo crucial sobre un modelo relacionado. Entonces implementamos un hack que implica N+1 peticiones mientras nos quejamos de los desarrolladores del backend que se apresuran a añadirlo rápidamente. Este no suele ser el caso con una API GraphQL bien implementada, ya que podemos profundizar en los datos tanto como queramos. ¿Necesita ver la dirección de un cliente en un pedido de este lote? No hay problema, al menos en teoría, lo que nos lleva a...
La complejidad es más difícil de prever
Cuando se diseña GraphQL desde el lado del back-end puede ser difícil pensar en toda la profundidad que un cliente puede profundizar en el gráfico. Hay un montón de maneras de instrumentar y observar el uso de su gráfico, y después de dejar que sus colegas de front-end jueguen un rato puede empezar a ver algunas consultas largas realizando lecturas bastante imaginativas en su almacén de datos. En una API REST esto es más fácil de controlar, ya que puedes determinar fácilmente el alcance de los datos a los que se accederá en una única solicitud. A menudo esta complejidad perdida puede morderte duro una vez que se libera a la producción. Muchas de esas veces tampoco es obvio cómo escapar de este agujero que os habéis cavado.
Las páginas numeradas son muy difíciles
Esta es una queja que en realidad es irónica. Definitivamente se puede sentir que GraphQL fue diseñado en y para Facebook al ver la forma en que funciona su mecanismo de paginación. Las llamadas Conexiones son básicamente flujos interminables de aristas de grafos, cuya navegación se realiza a través de cursores en lugar de las páginas más clásicas. Aunque es fácil ver cómo encaja esto con un feed interminable de publicaciones al estilo de Facebook, si quieres una lista ordenada y paginada con la posibilidad de ir, por ejemplo, a la página 42, lo vas a tener mucho más difícil. Por supuesto, hay formas de evitarlo, pero eso es lo que son: soluciones.
¿Lo volveríamos a hacer?
Con todas las quejas y diferencias enumeradas anteriormente, probablemente pienses que estamos tratando GraphQL como un experimento que se estropeó y volvimos directamente a las API REST. Eso no es cierto. En todo caso, estamos trabajando para utilizar GraphQL más ampliamente en proyectos en toda la organización. Es una gran tecnología que ha facilitado y mejorado nuestro trabajo. Sin embargo, al principio invertimos en GraphQL sin darnos cuenta del tipo de dolores de crecimiento por los que pasaríamos.
Si crees que GraphQL puede ser adecuado para ti, te animo a dar el paso. Dedícate el tiempo y el espacio necesarios para fallar con seguridad, ¡y no tardarás en cosechar los beneficios!
Lea también:
– ¿Cómo gestionar eficazmente a los desarrolladores remotos? La guía para CTO
– Python vs. Ruby? ¿Qué tecnología debería utilizar para el desarrollo de productos?
– Una guía rápida para crear y desarrollar su propio mercado. ¿Qué merece la pena saber?