Introducción
Veo venir algunos grandes cambios sobre el consumo de API’s en internet. La llegada de GraphQL ya tiene un poco de tiempo, sin embargo su uso no está tan extendido como REST.
A lo largo de los años hemos ido evolucionando. Pasamos por SOAP, luego por REST y finalmente vamos hacia GraphQL.
Claro que ni SOAP ni REST son malos, que los use quien quiera y lo respeto. Sin embargo vamos a ver qué ventajas tiene GraphQL contra REST.
¿Qué es GraphQL?
Vamos a crear una definición sencilla sin tantas formalidades.
GraphQL es una nueva forma de consumir un servicio web. Es un estándar, no es un lenguaje de programación ni un framework ni librería.
Es como JSON; JSON no es un lenguaje de programación ni framework ni librería, es una especificación. Todos conocemos JSON, y cada lenguaje de programación lo implementa a su modo pero al final es un estándar con el que todos los lenguajes que lo soporten se pueden comunicar.
Lo hizo Facebook al ver que a veces sobrecargaba al servidor con múltiples peticiones, además de tener múltiples rutas.
¿Qué es REST?
Igualmente es una especificación que usa los verbos HTTP para realizar acciones. Es expresivo por sí mismo. Hacemos peticiones y cambiamos la ruta dependiendo de cada acción.
Por ejemplo, para eliminar es la petición DELETE. Para editar es PUT, para obtener es GET y para insertar es POST.
No hay que apegarnos a un verbo, podemos usarlo como queramos pero es recomendable usarlo así.
Personalmente todas (o la mayoría) de las apps que he creado usan REST.
Aquí un ejemplo de REST con PHP: Axios y PHP: ejemplos de peticiones AJAX
GraphQL vs REST
Pongamos el ejemplo de un CRUD de mascotas.
Con REST
Para ver una mascota por id ejecutamos una petición GET algo así:
servidor.com/mascota/1
Si queremos una con el id 2:
servidor.com/mascota/2
Ver todas las mascotas:
servidor.com/mascotas
Obtener amigos de la mascota con el id 3:
servidor.com/amigos/mascota/3
Eliminar una mascota: podemos hacer una petición DELETE y pasar el id:
servidor.com/mascota/1
Crear una mascota, hacemos una petición POST a la ruta:
servidor.com/mascota
Y en el cuerpo pasamos la mascota.
Problemas con REST
Así nos llevamos nuestra app. Y todo va perfectamente bien. El problema viene cuando sobran datos o faltan datos.
Sobran datos
Por ejemplo, tal vez al consultar todas las mascotas salga esto:
Pero ahora ponemos eso en una app para Android en donde sólo es necesario mostrar el nombre de la mascota. Entonces, ¿para qué sirve la edad? ahí ya sobran datos.
Bueno, entonces decimos que no hay problema, simplemente no los mostramos. Ahora imagina que tu app se consume por 4G (o como se le diga a las redes de teléfonos) y que hay 10 mascotas.
Imagina cuánto ancho de banda se está desperdiciando, y cuánto saldo está gastando el usuario en vano (o bueno, en mi país tercermundista el saldo sí se gasta)
Esto es para una app de mascotas, pero ahora imagina una que sí sea real, que sí tenga datos, que sean datos complejos, etcétera.
Faltan datos
Ahora veamos otra cosa. Suponemos que en la misma app tocamos una mascota y se listan los detalles de la misma, así como sus amigos.
Para los detalles de la mascota llamamos a servidor.com/mascota/1
Y para los amigos llamamos a servidor.com/amigos/mascota/1
¿Ya viste? dos llamadas al servidor. Ahora multiplica eso por 20 usuarios concurrentes, son 40 peticiones al mismo tiempo.
Peticiones que con GraphQL puedes ahorrarte.
Sigamos imaginando y ahora aparte de sus amigos quiero ver sus comidas favoritas (suena tonto pero recuerda que es un ejemplo).
Entonces para obtener sus comidas llamamos a servidor.com/comidas/mascota/1
Ya van 3 llamadas al servidor. Y así podemos seguir.
GraphQL al rescate
Este estándar o como se le diga nos viene a salvar, ya que ahora no creamos muchas rutas, de hecho se puede correr todo en la misma ruta, por ejemplo:
servidor.com/api
Lo que hace tan maravilloso a GraphQL es que es como un juego de preguntas y respuestas. Tú le mandas lo que quieres, y te mandará únicamente eso.
Veamos el ejemplo para consultar una mascota:
{
mascota(id: 1){
nombre,
edad,
}
}
Eso que ves es lo que se manda al servidor. Simplemente se serializa y el servidor se encarga de hacer el proceso inverso, leerlo, y responder.
Tranquilo, se ve complicado pero no. Vamos paso por paso.
Primero le decimos que queremos la mascota en donde el id sea 1. Es importante notar desde aquí el tipado fuerte, pues le pasamos un entero. Si fuera una cadena la pondríamos entre comillas.
Y luego, entre las llaves le decimos que queremos el nombre y la edad. Eso fue para consultar una mascota. Para consultarlas a todas tal vez:
{
mascotas{
nombre,
edad,
}
}
Ahí usamos el plural de mascota.
Sobran datos
No, no sobran datos. Si vamos a mostrar en nuestra app únicamente el nombre, cambiamos la consulta a:
{
mascotas{
nombre,
}
}
Sí, sólo le decimos que nomás queremos el nombre, y la edad no.
Faltan datos
Tampoco faltan datos. Si vamos a mostrar los detalles de una mascota, así como sus amigos y comidas hacemos esta petición:
{
mascota(id: 1){
nombre,
edad,
amigos{
nombre,
},
comidas{
nombre,
},
}
}
Oh sí, sólo una petición y traerá todos los datos que pedimos. Notar por favor que, como comidas es otro objeto, especificamos cuáles campos queremos, al igual que los amigos. De esta manera no sobran datos ni faltan, tenemos sólo lo necesario,
¿Y cómo se usa GraphQL con los lenguajes de programación?
Como lo dije, es un estándar y no depende del lenguaje. Ya hay especificaciones para los lenguajes que (según yo) son más populares. Por ejemplo PHP, Golang y JavaScript.
Eso es la implementación en el servidor, pues para hacer peticiones del cliente podemos usar incluso la URL. He probado un ejemplo y se ve así:
http://localhost:8080/product?query={product(id:1){name,info,price}}
La consulta es mandada directamente en la URL. Ahí estamos consultando el producto con el id 1, y queremos que traiga el nombre, información y precio.
Aquí el resultado:
Seguramente ya lo dije, pero lo diré de nuevo: es simplemente mandar una cadena que llevará la consulta, el servidor se encarga de entenderlo.
Pronto escribiré tutoriales sobre la implementación de GraphQL en los distintos lenguajes de programación.
¿Cómo se comunica?
Mandamos en el cuerpo (o puede ser en la URL) la petición en forma serializada. Luego el servidor hace el proceso inverso.
Por ejemplo, tenemos esta consulta:
{
producto(id: 1){
nombre,
info,
precio,
}
}
Al serializarla se puede convertir en esto:
{producto(id:1){name,info,price,}}
Aunque ahora que lo pienso no es tanto una serialización, es más bien remover espacios y saltos de línea. De hecho es una simple cadena que se manda, pero se parece mucho a JSON.
También se puede enviar en el body de la petición HTTP.
Conclusión
Para terminar aquí dejo la página oficial del estándar para que te informes un poco más.