Conociendo GraphQL

por Ricardo Vega el 19 de octubre, 2020
Etiquetas:
ProgramaciónJavascriptBackendDatos
7 minutos.

Hoy quiero traer al blog una tecnología que lleva dando que hablar desde 2015, momento en el que Facebook la libera públicamente tras 3 años como herramienta interna. GraphQL representa una alternativa al archiconocido REST e intenta solucionar un problema al que seguramente te hayas enfrentado si alguna vez has construido una aplicación web o una aplicación móvil que consume APIs: el gran número de llamadas que es necesario realizar para poder pintar una pantalla concreta.

Aunque verás algun definción y query, este post es una introducción que busca mostrar por qué aparece GraphQL, presentándolo como una alternativa previa. No se trata de un tutorial ni un "Primeros Pasos"

En los últimos años ha existido una tendencia clara para generar aplicaciones cliente que consuman datos del servidor, desacoplando la parte cliente de la servidora tanto en aplicaciones móviles como webs (el patrón SPA del que ya hemos hablado). De igual modo, en el servidor se ha tendido ha realizar cada vez APIs más atómicas, encontrando en el paradigma de los microservicios el mayor representante de dicha tendencia.

Estas dos formas de realizar aplicaciones, ha ayudado a construir aplicaciones más desacopladas y más fáciles de escalar pero también ha introducido problemas como el que GraphQL pretende solventar. Pensemos que por un lado tenemos clientes (aplicaciones web o aplicaciones móviles) que se comunican con el servidor a través de REST y por otro lado tenemos una gran cantidad de "servidores", cada uno exponiendo su API de forma genérica lo cual no tiene por qué encajar con las necesidades de la aplicación web, lo que da lugar a llamadas REST por parte de los clientes muy poco eficientes:

  • Muchas llamadas para unir información de diferentes APIs y poder contar con toda la información necesaria para pintar una pantalla.
  • Llamadas que nos devuelven contenido que no necesitamos. Por ejemplo, imagina que necesitamos recuperar el nombre del usuario y para ellos consumimos el API de usuarios, pero esta, a parte del nombre nos está devolviendo los apellidos, la edad y dónde vive. Toda esa información, consume recursos y ancho de banda pero no se usa para nada.

Es por esto que nace el patrón BFF o Backend for Frontend como un agregador de diferentes APIs para adaptarlas al cliente y así hacerlas específicas a este. Pero esta aproximación también presenta ciertos problemas como el acople tan fuerte que hay entre cliente y BFF (un cambio de funcionalidad, afecta a ambos), como que si queremos realmente optimizar el BFF, deberíamos tener un BFF por cliente o lo que es lo mismo, imagina que tenemos una funcionalidad muy semejante en una aplicación web y en una aplicación móvil aunque no hacen exactamente lo mismo. Pues o bien tenemos un BFF compartido que devuelva la información que necesitan ambos (a riesgo de estar devolviendo a veces más información de la que un cliente en concreto precisa) o bien nos toca hacer dos BFFs.

En este contexto nace GraphQL que es un lenguaje con el cual podemos realizar consultas (lecturas) y mutaciones (operaciones) de los datos empleados por una aplicación SPA o móvil, permitiendo optimizar el proceso al pedir o enviar exactamente la información que necesitamos para cada momento.

Aunque GraphQL cuenta con implementaciones y clientes en gran número de tecnologías, por debajo emplea una sintaxis sencilla y semántica (es fácil leer el código y saber qué estamos haciendo) empleando el concepto de "grafo" como elemento central sobre el que debemos modelar la capa de datos de nuestra aplicación.

La teoría de grafos es muy amplia y compleja, escapando por completo del alcance de este post.

Principalmente, un servidor de GraphQL publica un único endpoint que es el punto de entrada de las aplicaciones que lo consuman, dejando a estas solicitar la información que necesitan mientras el servidor "sabe" dónde tiene que ir a buscar esa información. Entrecomillo "sabe" porque esa parte la deberemos programar nosotros, el servidor de por sí no tiene información ni conoce cómo recuperarla si nosotros no le decimos cómo.

En definitiva, en GraphQL tenemos una arquitectura cliente-servidor.

Es importante destacar que al igual que GraphQL no impone un lenguaje de programación ni para la parte cliente ni para la servidora, tampoco tiene restricciones respecto a la base datos o sistema de almacenamiento puesto que simplemente hace de "puente".

Todo parte de la definición de un esquema de datos que se alojará en el servidor y servirá como base tanto a clientes como servidor para conocer la estructura de datos que va a tener el API:

1type Query {
2 me: User
3}
4
5type User {
6 id: ID
7 name: String
8 email: String
9}

Como hemos comentado anteriormente, deberemos indicarle al servidor cómo debe obtener esa información y para ello podremos usar funciones y resolvers. Esta parte ya estará escrita usando el lenguaje de programación en el que estemos programando y tendremos libertad para implementarlo como deseemos.

Por ejemplo, en javascript:

1function Query_me(request) {
2 return request.auth.user;
3}
4
5function User_name(user) {
6 return user.getName();
7}
8
9function User_email(user) {
10 return user.getEmail();
11}

A partir de aquí, nuestro servidor tendría un esquema y sabría cómo rellenar los datos que lo conforman por lo que podríamos empezar a hacer queries con nuestro cliente. Por ejemplo:

1{
2 me {
3 name
4 }
5}

Lo que produciría el siguiente JSON:

1{
2 "me": {
3 "name": "Luke Skywalker"
4 }
5}

Como ves, nos está devolviendo estrictamente lo que hemos pedido. Hemos definido en el esquema un parámetro "email", pero no está en la respuesta ya que no estaba previsto en la query.

Además, dentro del lenguaje se considera el uso de variables para definir parámetros dentro de nuestras queries. Es decir, es perfectamente valido hacer queries especificando parámetros concretos de filtrado / búsqueda y por tanto reproducir consultas del tipo "dame los usuarios cuyo email es blabla@gmail.com" o "actualiza el email del usuario con id igual a 1234".

Si existen operaciones de escritura, estas también deberán estar definidas en el servidor, en este caso, como mutaciones para las cuales igualmente habrá que definir su implementación a través de resolvers como para las consultas.

GraphQL nos permite también definir tipos personalizados, fragmentos para no repetir siempre el mismo código dentro de la definición y consulta de nuestras queries, alias o directivas para mejorar el mantenimiento y comprensión de nuestro esquema de datos.

La verdad que GraphQL tiene contenido como para más de un post y no es mi objetivo con esta entrada profundizar en él o montar un tutorial sino más bien darte a conocer que existe una alternativa a REST válida, no especialmente complicada de implementar y que soluciona un problema que existe aunque también introduce nuevos retos como su escalado (tema que merece también post propio).

Hoy por hoy, quería simplemente mostrarte algún ejemplo sencillo (he usado los de la web de GraphQL) para que veas "qué pinta tiene". Si estas interesado en que haga un tutorial (o serie de ellos) entrando realmente en su sintaxis e implementación, házmelo saber 😃.

De momento, te dejo algunos enlaces que creo que pueden ser buenos puntos de partida si quieres ir un paso más allá:

Un saludo,

Ricardo

Discutir en Twitter

Compartir artículo
Ricardo Vega es un desarrollador "full-stack" al que le gusta "cacharrear con todo" pero está especializado sobre todo en tecnologías Javascript, principalmente en React. Intenta devolver a Internet lo que Internet le ha dado.

Sigue leyendo 😀


Apoya al blog


Si te ha gustado este artículo, valora apoyarme económicamente a través de Patreon, una plataforma de Micro-mecenazgo con la que puedes hacerme un donativo que ayude a la continuidad del blog. Una pequeña ayuda significa mucho.

Permanezcamos en contacto!


¿Quieres enterarte de todas las novedades del sector? ¿Te gustaría trabajar conmigo? ¡Puedes contactar conmigo de forma muy sencilla!

@ricveal

ricardo.vega@ricveal.com

Ricardo Vega