Índice

Ventajas del uso de GraphQL sobre las API REST

Uno de los problemas más comunes de REST es la sobrecarga o infracarga de datos. Esto ocurre porque la única forma de que un cliente descargue datos es accediendo a puntos finales que devuelven estructuras de datos fijas. Es difícil diseñar la API para que pueda proporcionar a los clientes los datos exactos que necesitan.

  • GraphQL reduce las peticiones de red al permitirnos obtener o recuperar todos los datos que necesitamos en una sola consulta.
  • Con GraphQL, no hay necesidad de versionado, ya que podemos añadir fácilmente nuevos campos y tipos a nuestra API GraphQL sin afectar a las consultas existentes. Además, podemos marcar fácilmente los campos como obsoletos, y los campos serán excluidos de la respuesta recibida del servidor.
  • Con GraphQL, también puede realizar un seguimiento de bajo nivel del rendimiento de las solicitudes procesadas por su servidor. GraphQL utiliza el concepto de funciones de resolución para recopilar los datos que solicita un cliente. Instrumentar y medir el rendimiento de estos resolvers proporciona información crucial sobre los cuellos de botella en su sistema.

Breve explicación del funcionamiento de GraphQL

La implementación de GraphQL consta principalmente de tres partes

  • Esquema - Describe los datos.
  • Resolvers - Lógica para obtener datos de diferentes recursos (microservicios).
  • Consulta - El cliente pregunta qué datos debe obtener.

Esquema(Más información sobre esquemas y tipos)

➡️
type Query{getUsers:[User]getUser(user_id:Int!):User}type Mutation{addUser(first_name:String!,last_name:String,pic:String):Boolean deleteUser(user_id:Int!):Boolean}type User{first_name:Stringlast_name:Stringpic:Stringfull_name:Stringuser_id:Int!designation:String}

El código anterior describe lo que se puede consultar y los datos de respuesta (tipo de datos) que se esperan de los recursos.

P.D: "!" significa que el campo no puede ser nulo o indefinido.

Resolvers (El siguiente código está escrito en NodeJs)

➡️
{Query:{getUsers:(obj,args,context,info) => { return users},getUser:(obj,{user_id},context,info) => { return users.find(user => user.user_id == user_id) } },Mutation:{ addUser:(obj,{first_name,last_name,pic},context,info) => { users.push({ first_name:first_name, last_name:last_name, pic:pic }) return true },deleteUser:(obj,{user_id},context,info) => { for (var i = 0; i < users.length; i++) { if(users[i].user_id == user_id){ users.splice(i,1) return true }}return false } }, User:{ full_name:(prev_obj,args,context,info) => { return `${prev_obj.first_name} ${prev_obj.last_name}`}}}

El código anterior describe la lógica que se ejecuta cuando el cliente realiza una solicitud.

P.D. He utilizado la función full_name resolver para el tipo User para escribir mi propia lógica.

Consulta(Más información sobre la consulta)

➡️
{getUsers{full_name pic}}

Elcliente consulta utilizando el código anterior que devuelve sólo full_name y pic como a continuación.

P.D. El cliente sólo puede consultar los campos definidos en el esquema.

➡️
{"data":{"getUsers":{"full_name":"Srinivasa Sainath", "pic":"https://vpms.xoxoday.com/images/xoxoday.png"}}}

La petición del cliente puede ser de Consulta y Mutación ( y Suscripción. Esto se discutirá en futuros blogs de la serie GraphQL).

Ambas peticiones hacen lo mismo. Excepto que la mutación se ejecuta de forma sincrónica. La convención que se sigue es que Mutation se utiliza para cualquier operación que cause escrituras en el servidor (actualizar perfil, crear pedido, etc.) y una consulta se utiliza para obtener datos (obtener menú, obtener lista de vales, etc.). ( Similar a GET y POST ). Técnicamente, ambos tipos de peticiones se pueden utilizar para realizar cualquier lógica. Pero es mejor seguir la convención, ya que ayuda a su equipo.

Puntos importantes para comprender la relación entre las funciones de resolución y la consulta

  • Puedes pensar en cada campo de una consulta GraphQL como una función o método del tipo anterior que devuelve el tipo siguiente. Así es precisamente como funciona GraphQL. Cada campo de cada tipo está respaldado por una función llamada resolver, proporcionada por el desarrollador del servidor GraphQL. Se llama al resolver correspondiente para producir el siguiente valor cuando se ejecuta un campo.
  • La ejecución se completa si un campo produce un valor escalar como una cadena o un número. Sin embargo, si un campo tiene un valor de objeto, la consulta contendrá otra selección de campos que se aplican a ese objeto. Esto continúa hasta que se alcanzan los valores escalares. Las consultas GraphQL siempre terminan en valores escalares.

Una función de resolución recibe cuatro argumentos

Sintaxis :

➡️
{getUsers:(obj,args,context,info) =>{ return users }}
  • obj El objeto anterior, que para un campo del tipo Query raíz a menudo no se utiliza.
    Para la comprensión, más acerca de este argumento consulte GraphQL Server With Node.js.
  • args Los argumentos proporcionados al campo en la consulta GraphQL. En la función de resolución anterior {user_input} son los argumentos
  • context Valor que se proporciona a cada resolver y que contiene información contextual importante, como el usuario conectado en ese momento o el acceso a una base de datos. En el resolver anterior, la función context se utiliza para pasar token_info
  • info Valor que contiene información específica del campo relevante para la consulta actual, así como los detalles del esquema. A menudo no se utiliza
➡️
Clone the demo GraphQL project from here.P.S. In the next part of the GraphQL series, I will discuss how to implement GraphQL as an API Gateway.
Srinivasa Sainath

Srinivasa Sainath