Escritores tecnológicos

GraphQL en aplicaciones dotNET

Minutos 9

En este artículo hablaré de GraphQL con enfoque en aplicaciones dotNet. Aquí te mostraré cómo problemas inherentes de REST motivó la creación de GraphQL. A continuación, presentaré los conceptos básicos de la especificación de este lenguaje. Posteriormente presentaré el biblioteca de chocolate caliente, que es una de las muchas bibliotecas que implementan la especificación GraphQL. Finalmente, mostraré un pequeño ejemplo del uso de esta biblioteca en una aplicación dotNet. 

RESTO

Antes de hablar de GraphQL, es necesario hablar de REST. El término fue acuñado por Roy Thomas Fielding (2000) en su tesis de doctorado. En este trabajo, Fielding presenta REST como un patrón arquitectónico para aplicaciones web definido por cinco restricciones: 

  • Servidor de cliente: Esta restricción define que la interfaz de usuario debe estar separada de los componentes del sistema que procesan y almacenan datos. 
  • Apátrida: Esta restricción dice que el cliente no necesita estar al tanto del estado del servidor, ni el servidor necesita estar al tanto del estado del cliente. 
  • Caché: Esta restricción indica que, cuando sea posible, la aplicación del servidor debe indicar a la aplicación del cliente que los datos se pueden almacenar en caché. 
  • Sistema de capas: Esta restricción indica que la aplicación debe construirse apilando capas que agreguen funcionalidad entre sí. 
  • Interfaz uniforme: Esta restricción indica que los recursos de la aplicación deben estar disponibles de manera uniforme, de modo que, al aprender a acceder a un recurso, automáticamente se sepa cómo acceder a los demás. Según el trabajo de Fielding, esta es una de las características centrales que distinguen a REST de otros patrones arquitectónicos. Sin embargo, el propio autor afirma que esto degrada la eficiencia de la aplicación, ya que los recursos no están disponibles de una manera que satisfaga las necesidades específicas de una aplicación determinada. 

Cómo se ve REST en la práctica

En la Figura 1 puedes ver parte de la API OneDrive de Microsoft. En esta imagen se puede ver la uniformidad en el acceso a los recursos. Esto se nota cuando notamos que, para obtener datos, simplemente se envía una solicitud GET a un punto final que comienza con el término unidad y va seguido del nombre del recurso y su ID. La misma lógica se aplica a la creación de recursos (POST), modificación de recursos (PUT) y eliminación de ellos (DELETE). 

Accediendo a la documentación Google Drive, podemos ver el retorno típico de una API REST. La documentación antes mencionada muestra el gran volumen de datos que puede traer una sola solicitud REST. A pesar de ser grande, es posible que una aplicación cliente aún necesite realizar solicitudes adicionales para obtener más datos sobre el propietario de un archivo, por ejemplo. 

Considerando las restricciones determinadas por Fielding y los ejemplos mostrados, es fácil ver dos problemas inherentes a REST. El primero de ellos es el tráfico de datos que el consumidor no necesita y el segundo es la posible necesidad de realizar varias solicitudes para obtener los datos necesarios para crear una página web. 

Figura 1 - Acceda al artículo completo aquí.

Entendiendo GraphQL

GraphQL surgió en 2012 en Facebook como una solución a problemas encontrados en el patrón REST. En 2015, el lenguaje pasó a ser de código abierto y en 2018 se creó la Fundación GraphQL, que se encargó de especificar la tecnología. 

Es importante resaltar que GraphQL no es una biblioteca o herramienta. Al igual que SQL, GraphQL es un lenguaje para buscar y manipular datos. Mientras usamos SQL en la base de datos, GraphQL se usa en las API.

La Tabla 1 muestra una expresión SQL para recuperar un número de pedido y un nombre de cliente de una base de datos. De manera similar, la Tabla 2 muestra una expresión GraphQL para obtener los mismos datos de una API que admite GraphQL. En los ejemplos, podemos ver dos ventajas principales de GraphQL sobre REST. El primero está presente en el hecho de que GraphQL permite al consumidor buscar únicamente los datos que necesita para crear su página web. El segundo está presente en que el consumidor podría buscar los datos del pedido y del cliente en una sola llamada. 

Tabla 1: Ejemplo de selección en una base de datos relacional. 
Tabla 2: Ejemplo de una expresión GraphQL.

Considero interesante mencionar dos características más de una API GraphQL. El primero de ellos es la existencia de un único punto final. A diferencia de REST, donde se crea un punto final para cada recurso, en una API GraphQL todas las consultas y mutaciones se envían al mismo punto final.  

El segundo es el hecho de que una API GraphQL solo admite el verbo POST. Esta es otra diferencia más en relación con un REST, donde se deben usar diferentes verbos HTTP dependiendo de la intención de la solicitud. Por lo tanto, mientras en una API REST debemos usar los verbos GET, POST, PUT y DELETE, en una API GraphSQL usaremos el verbo POST para obtener, crear, cambiar y eliminar datos.  

Lenguaje de definición de esquemas

Hablemos ahora un poco sobre SDL (Lenguaje de definición de esquemas). Cuando se utiliza una base de datos relacional, primero es necesario definir el esquema de la base de datos, es decir, es necesario definir las tablas, columnas y relaciones. Algo similar ocurre con GraphQL, es decir, la API necesita definir un esquema para que los consumidores puedan buscar los datos. Para crear este esquema, se utiliza SDL.  

El sitio web oficial de GraphQL tiene una sección dedicada a SDL. En esa sección puede encontrar una descripción completa del lenguaje para crear esquemas GraphQL. En este texto, presentaré la sintaxis básica para crear un esquema GraphQL. En la Figura 2 puede ver parte de un esquema GraphQL creado usando el Apollo. Podemos ver que el esquema comienza con la definición de dos tipos fundamentales: Consulta y Mutación. En el primer tipo definimos todas las consultas que tendrá nuestra API. En nuestro ejemplo, los consumidores podrán buscar clientes, productos y pedidos. El tipo de mutación define qué operaciones de manipulación de datos estarán disponibles para el consumidor. En el ejemplo presentado, el consumidor podrá crear, cambiar y eliminar clientes y productos. Sin embargo, cuando se trata de pedidos, puede crear, agregar un artículo, cancelar y cerrar el pedido. 

Además de los tipos Consulta y Mutación, puede ver la presencia de los tipos Cliente y Producto. En ambos, hay propiedades ID, String y Float. Estos tres tipos, junto con los tipos Int y Boolean, se denominan tipos escalares. El esquema también muestra la definición de una enumeración denominada OrderStatus. La Figura 3 muestra la definición de tipos de entrada que se utilizan para proporcionar datos de entrada para consultas y mutaciones. 

Creo que es importante señalar que la forma de crear el esquema varía según la biblioteca que elijas. Cuando se utiliza la biblioteca Apollo para javascript, la definición del esquema se puede realizar a través de una cadena pasada como parámetro a la función gql o mediante la creación de un archivo (generalmente llamado esquema.graphql). Sin embargo, cuando se utilizan bibliotecas como Hot Chocolate para dotNet, la definición del esquema se realiza mediante la creación de clases y la configuración de servicios en la aplicación. Por tanto, la forma en que se crea un esquema GraphQL puede variar mucho según el lenguaje y la biblioteca elegidos.  

Figura 2.
Figura 3.

Elementos básicos del lenguaje GraphQL.

Como se mencionó anteriormente, GraphQL es un lenguaje y, por lo tanto, tiene una sintaxis. Puedes encontrar la guía completa con la sintaxis del idioma en la web oficial de GraphQL. Sin embargo, en este artículo describiré sus elementos básicos.  

La búsqueda de datos se realiza mediante consultas, las cuales deben comenzar con la palabra clave. pregunta seguido del nombre de la consulta. Si tiene parámetros, debe ser paréntesis abiertos y, dentro de ellos, deberás colocar el nombre de cada parámetro seguido de su valor. Tú dos puntos (:) debe usarse para separar el nombre del parámetro de su valor. Una vez finalizada la lista de parámetros, debe cerrar los paréntesis. Entonces, debes llaves abiertas ({) y pon el nombre de los campos que quieras dentro de ellos. Con la lista de campos finalizada, debes cerrar la llave  (}). La Tabla 3 muestra un ejemplo simple de una consulta. 

Tabla 3: Ejemplo de consulta.

Hay escenarios en los que los parámetros de consulta pueden ser complejos. Cuando un parámetro es complejo, es decir, es un objeto con uno o más campos, se deben abrir llaves inmediatamente después de los dos puntos. Dentro de las claves se debe colocar el valor de cada campo del objeto y su respectivo valor, ambos deben estar separados por dos puntos (ver tabla 4). 

También hay escenarios en los que los campos de consulta pueden ser complejos. En estos casos, debe abrir llaves justo después del nombre del campo. Dentro de las claves, debes colocar los nombres del campo objeto (ver tabla 5). 

Tabla 4: Ejemplo de consulta.
Tabla 5: Ejemplo de consulta.

Las reglas descritas hasta ahora también se aplican a las mutaciones. Sin embargo, estos deben comenzar con la palabra clave. crianza de organismos con mutación deseada en lugar de consulta. Es interesante observar que existen otros elementos en la sintaxis de GraphQL, pero los elementos descritos hasta ahora son suficientes para ejecutar la mayoría de consultas y mutaciones. 

Al ser un lenguaje, GraphQL debe ser implementado mediante alguna aplicación o biblioteca. Para que nuestra API admita consultas y mutaciones, generalmente necesitamos una biblioteca. Por supuesto, podríamos implementar la especificación del lenguaje por nuestra cuenta, pero eso sería muy improductivo. La sección “Código” del sitio web GraphQL.org muestra una lista de bibliotecas que implementan GraphQL para los más variados lenguajes. Para el mundo dotNet, por ejemplo, existen las bibliotecas “GraphQL para .NET”, “Hot Chocolate” y otras. 

Cuando se habla de implementaciones GraphQL, es necesario hablar del concepto de “resolvedores”. Un solucionador es una función activada por la biblioteca que implementa GraphQL. Esta función es responsable de recuperar de manera efectiva los datos solicitados por la consulta. Lo mismo ocurre con las mutaciones, es decir, cuando la biblioteca recibe una solicitud para ejecutar una mutación, la biblioteca identifica el solucionador que ejecutará los cambios en la base de datos (insertar, actualizar y eliminar). Nótese, entonces, que en la mayoría de bibliotecas las búsquedas y cambios de datos se realizan mediante su propio código. Se puede ver, entonces, que las bibliotecas que implementan GraphQL son responsables de interpretar la consulta/mutación enviada por el llamante y descubrir la función adecuada para resolver la consulta/mutación solicitada. Para ver un ejemplo de una API simple que usa Hot Chocolate, visite mi GitHub

En definitiva, GraphQL es un lenguaje creado por Facebook con el objetivo de superar los problemas inherentes a REST. El lenguaje proporciona una sintaxis simple para obtener datos de una API y cambiar datos de ella. Se implementa mediante una amplia variedad de bibliotecas para los idiomas más diversos, lo que permite al desarrollador crear una API GraphQL utilizando su idioma favorito.

Referencias

"GráficoQL". Wikipedia, 9 de junio de 2022, en.wikipedia.org/wiki/GraphQL. Consultado el 6 de noviembre de 2023. 

La Fundación GraphQL. "GraphQL: un lenguaje de consulta para API". Graphql.org, 2012, graphql.org/. 

Thomas Fielding, Roy. "Disertación de campo: CAPÍTULO 5: Transferencia de estado representacional (REST)". ics.uci.edu, 2000, ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm. Consultado el 6 de noviembre de 2023. 

Deja un comentario

Su dirección de correo electrónico no será publicada. Los campos necesarios están marcados con *