GraphQL
INTRODUCCIÓN
Para hablar de GraphQL es imposible no hacer una breve introducción de qué es REST con el objetivo de entender por qué nace, y qué necesidades intenta cubrir en el mundo del diseño de las API’s.
REST
Llevamos muchos años trabajando y diseñando API’s REST. Son una pieza fundamental en las aplicaciones modernas, ya que este protocolo de intercambio de datos lleva con nosotros desde el año 2000, y es una de las primeras opciones que tenemos en cuenta cuando necesitamos desarrollar una API.
Con esta forma tradicional de construir API’s, el servidor expone varios endpoints que pueden ser de distinto tipo: GET, POST, PUT, PATCH…. Y que son representados con una URL distinta que identifica a cada uno de los recursos expuestos. En este caso comprobamos como a través de la URL /product/1 podemos obtener la información almacenada sobre un producto en concreto.
Como se puede deducir, REST hace que tengamos que hacer distintas peticiones a distintos recursos para obtener la información que podamos necesitar.
De esta manera ganamos independencia entre tipos de lenguajes, separación entre cliente y servidor, fiabilidad, escalabilidad… y una infinidad de ventajas más en la que no entraremos en detalle ya que el objetivo de este post es conocer GraphQL y ventajas que le hacen destacar frente a REST.
GraphQL
En el año 2015 Facebook lanza una release de una nueva herramienta que permite construir API’s que rompe con el tradicional REST, se trata de GraphQL.
La principal diferencia con REST es que el lenguaje que se usa en una petición hecha con GraphQL es el mismo que el que obtenemos en la respuesta.
Esto significa que cuando el endpoint de GraphQL es llamado, debemos hacerlo con la información que queremos tener disponible en la respuesta, y éste devolverá exactamente esta información, ni más ni menos, y con una sola petición en lugar de hacer varias peticiones a distintos endpoints.
Como podemos ver en esta petición GraphQL, solicitamos el pedido con identificador número 1, y también los campos ‘title’ y ‘description’ de cada producto incluido en este pedido, y en la respuesta obtendremos concretamente los campos solicitados en lugar de todos los campos de un producto.
Conceptos de GraphQL
Schema
En este punto debemos definir qué tipos de datos vamos a tener disponible en nuestra API y qué relación existirá entre ellos.
Define el contrato entre el cliente y servidor definiendo cómo los clientes pueden acceder a los datos, está escrito en GraphQL SDL (Schema Definition Language) y en el siguiente ejemplo se puede apreciar que es fuertemente tipado.
En nuestro ejemplo, el siguiente fichero order.graphqls será nuestro esquema:
Podemos definir varios tipos que serán las entidades que podemos obtener y consultar en las peticiones que lancemos al endpoint de GraphQL. La sintaxis es bastante sencilla de usar, con el símbolo ‘!’ establecemos que estos campos no pueden ser nulos, y para indicar que se trata de un array, solo hay que añadir el tipo entre corchetes, como se puede apreciar en el atributo ‘products’ del tipo ‘Order’.
Queries
Son los métodos para consultar información que queremos tener disponibles para usar cuando el endpoint único es llamado. (En el ejemplo anterior, getProductListOfOrder es una query).
En este caso, hemos definido 3 queries, ‘orders’ que devuelve un array del tipo ‘Order’, ‘order’ al cual le podemos enviar un identificador y devolverá la ‘Order’ correspondiente, y ‘getProductLIstOfOrder’ que devolverá un array de ‘products’.
Para implementar estas queries, solamente tendremos que implementar la interfaz GrahpQLQueryResolver disponible en la librería graphql-java-tools.
Mutations
Básicamente son ‘queries’, la única diferencia frente a éstas es que su objetivo no es consultar, si no modificar la información almacenada.
En nuestro ejemplo hemos creado una mutación que permite añadir un pedido a partir del identificador de un cliente y una lista de productos. Para implementar estas mutaciones, solamente tendremos que implementar la interfaz GrahpQLMutationResolver disponible en la librería graphql-java-tools.
NOTA: Puesto que es una mutación, utilizamos ‘OrderProductInput’ que en lugar de ser un objeto definido como ‘type’, se ha usado ‘input’. Se utiliza por convención con el objetivo de diferenciar el objeto que se utiliza como parámetro de entrada, al objeto que se utiliza en la respuesta del endpoint.
GraphiQL
Esta herramienta es activada por GraphQL, y nos permite utilizar una interfaz para construir consultas de una manera guiada y sencilla al endpoint.
Está activa en el path /graphiql de nuestro endpoint GraphQL y es un editor interactivo muy útil para trabajar con GraphQL ya que permite formatear las peticiones, y crea una pequeña documentación y autocompletado de las peticiones a realizar, lo que nos da un mundo de posibilidades para explorar la API disponible.
Como se puede ver en la imagen anterior, podemos construir una query en la columna de la izquierda, ejecutarla para obtener los resultados como se puede ver en la columna central, y un explorador con documentación sobre las queries y mutations disponibles en la API.
Si queremos obtener más información sobre los productos, solamente tendríamos que añadir un nuevo campo en la query:
Cabe destacar la funcionalidad de autocompletado que Graph_i_QL nos facilita. Otra de las ventajas de las que nos provee Graph_i_QL es la documentación, podemos ver el explorador a través del cual podemos navegar por los tipos, queries y mutations definidos en el schema:
La navegación por la documentación nos permite obtener información de la API sobre la que estamos trabajando.
Tanto las funciones de autocompletado como la documentación se generan automáticamente gracias al lenguaje tipado que ofrece GraphQL.
Toda la información es leída del contrato definido en el schema de GraphQL.
Conclusión: GraphQL vs REST
Es la cuestión que nos hacemos tras haber estado trabajando con GraphQL.
¿Es una nueva alternativa al tradicional REST para construir API?
¿Reemplazará en el futuro a las API REST que conocemos hasta ahora?
Estos son las principales ventajas y cambios que presenta GraphQL frente a REST para ayudarnos a decidir si optar por una opción u otra a la hora de diseñar nuestra API.
- Al tener únicamente un endpoint al que poder enviar qué información en concreto es la que queremos recuperar, de una sola petición obtenemos todos los datos que necesitamos, en lugar de tener que hacer múltiples peticiones para ir recuperando datos hasta obtener lo que necesitamos como en REST.
- Las repuestas son más ligeras, ya que solamente obtenemos los datos que necesitamos, no toda la información de una entidad.
- Al contrario que REST, GraphQL es mucho más flexible, ya que no hace falta ajustar el backend cuando alguna aplicación consume estos datos. Con GrahpQL podemos obtener los campos que queramos de ciertas entidades sin hacer ningún cambio.
- En cuanto el esquema es definido, frontend y backend pueden trabajar de manera independiente el uno del otro, ya que ambos conocen el contrato y pueden consumir cualquier tipo de datos siguiendo la estructura definida en éste.
- Al tener un lenguaje fuertemente tipado, tendremos documentación de manera autogenerada sobre el contrato definido.
Con el paso del tiempo se comprobará si GraphQL viene a sustituir a REST, personalmente creo que es una forma distinta de construir API’s que presenta muchas ventajas frente a REST y es un concepto innovador que rompe con algunos principios REST, pero no por esto hay que pensar en GraphQL como primera opción a la hora de desarrollar una API, ya que como sabemos, REST presenta multitud de ventajas a la hora de diseñar una API.