Tipos de Datos y Schemas en GraphQL – Parte 2 (Final)

8 minuto(s)

En la parte anterior llamada Tipos de Datos y Schemas en GraphQL – Parte 1, pudimos apreciar los primeros tipos de datps y schemas (esquemas) que tiene la tecnología GraphQL. Como mencione en la primera parte, estamos viendo una descripción técnica de estos tipos de datos, en otro post veremos a como consumir datos usando GraphQL, pero primero es importante conocer estos conceptos importantes sobre los tipos de datos y schemas. En este segunda parte y última veremos otro grupo de Tipos de Datos y Schemas en GraphQL, vamos con ello.

Partes

Antes de continuar te invito a escuchar el Podcast: “Si No Tienes Experiencia Para Un Puesto De Trabajo, Créala !” “Consejos Para Entrenar Tu Memoria de Programador” (Anchor Podcast): 

Spotify: Sound Cloud: Apple Podcasts Anchor Podcasts

Bien ahora continuemos con el Post: Tipos de Datos y Schemas en GraphQL – Parte 2 (Final). 

Tipos Escalares

Un tipo de objeto GraphQL tiene un nombre y campos, pero en algún momento esos campos deben resolverse en algunos datos concretos. Ahí es donde entran los tipos escalares: representan las hojas de la consulta.

Por ejemplo tenemos los siguientes datos :


De los datos anteriores, hacemos la siguiente consulta:


En la consulta anterior, los campos nombre y saboresDisponibles resolverán en tipos escalares, porque esos campos no tienen subcampos: son las hojas de la consulta.

GraphQL viene con un conjunto de tipos escalares predeterminados listos para usar:

Int: Un entero de 32 bits con signo.

Float: Un valor de punto flotante de precisión doble con signo.

String: Una secuencia de caracteres UTF‐8.

Boolean: true o false.

ID: Este tipo escalar representa un identificador único, que a menudo se usa para recuperar un objeto o como clave para un caché. El tipo de ID se serializa de la misma manera que una Cadena; sin embargo, definirlo como ID significa que no está destinado a ser legible por humanos.

En la mayoría de las implementaciones de servicios de GraphQL, también existe una forma de especificar tipos escalares personalizados. Por ejemplo, podríamos definir un tipo Date:


Luego depende de nuestra implementación definir cómo se debe serializar, deserializar y validar ese tipo. Por ejemplo, puedes especificar que el tipo Date siempre debe serializarse en una marca de tiempo de número entero, y tu cliente debe saber esperar ese formato para cualquier campo de fecha.

Tipos de Enumeración

También llamados Enums , los tipos de enumeración son un tipo especial de escalar que está restringido a un conjunto particular de valores permitidos. Esto te permite: 

  1. Validar que cualquier argumento de este tipo sea uno de los valores permitidos.
  2. Comunicar a través del sistema de tipos que un campo siempre será uno de un conjunto finito de valores.

Así es como se vería una definición de enumeración en el lenguaje de esquema GraphQL:


Esto significa que siempre que usemos el tipo Sabor en nuestro esquema, esperamos que sea exactamente uno de Fresa, Naranja o Papaya.

Ten en cuenta que las implementaciones del servicio GraphQL en varios lenguajes tendrán su propia forma específica de lenguaje para tratar con las enumeraciones. En lenguajes que admiten enumeraciones como un ciudadano de primera clase, la implementación podría aprovechar eso; en un lenguaje como JavaScript sin compatibilidad con enumeraciones, estos valores pueden asignarse internamente a un conjunto de enteros. Sin embargo, estos detalles no se filtran al cliente, que puede operar completamente en términos de los nombres de cadena de los valores de enumeración.

Listas y Non-Null

Los tipos de objetos, escalares y enumeraciones son los únicos tipos de tipos que puedes definir en GraphQL. Pero cuando usas los tipos en otras partes del esquema (schema), o en tus declaraciones de variables de consulta, puedes aplicar modificadores de tipo adicionales que afectan la validación de esos valores. Veamos un ejemplo:


Aquí, estamos usando un tipo String y marcándolo como no nulo agregando un signo de exclamación, ! después del nombre del tipo. Esto significa que nuestro servidor siempre espera devolver un valor no nulo para este campo, y si termina obteniendo un valor nulo, en realidad desencadenará un error de ejecución de GraphQL, lo que le informará al cliente que algo salió mal.

El modificador de tipo Non-Null también se puede usar al definir argumentos para un campo, lo que hará que el servidor GraphQL devuelva un error de validación si se pasa un valor nulo como ese argumento, ya sea en la cadena GraphQL o en las variables.

Obtenemos el siguiente error:


Al realizar la siguiente consulta:


Las listas funcionan de manera similar: podemos usar un modificador de tipo para marcar un tipo como List, lo que indica que este campo devolverá una matriz de ese tipo. En el lenguaje de esquema, esto se denota envolviendo el tipo entre corchetes [y ]. Funciona igual para los argumentos, donde el paso de validación esperará una matriz para ese valor.

Los modificadores Non-Null y List se pueden combinar. Por ejemplo, puedes tener una lista de cadenas no nulas:


Esto significa que la lista en sí puede ser nula, pero no puede tener ningún miembro nulo. Por ejemplo, en JSON:


Ahora, digamos que definimos una lista de cadenas no nulas:


Esto significa que la lista en sí no puede ser nula, pero puede contener valores nulos:


Puedes anidar arbitrariamente cualquier número de modificadores No nulos y de lista, según tus necesidades.

Interfaces

Como muchos sistemas de tipos, GraphQL admite interfaces. Una interfaz es un tipo abstracto que incluye un determinado conjunto de campos que un tipo debe incluir para implementar la interfaz.

Por ejemplo, podrías tener una interfaz Character que represente a cualquier usuario de una organización:


Esto significa que cualquier tipo que implemente Character necesita tener estos campos exactos, con estos argumentos y tipos de retorno.

Por ejemplo, aquí hay algunos tipos que podrían implementar Character:


Puedes ver que ambos tipos tienen todos los campos de la interfaz Character, pero también traen campos adicionales, deporteFavorito, totalCreditos y apellidos que son específicos para cada tipo de Humano en particular.

Las interfaces son útiles cuando deseas devolver un objeto o un conjunto de objetos, pero pueden ser de varios tipos diferentes.

Por ejemplo al hacer la siguiente consulta:


Se produce un error:


El campo usuario devuelve el tipo Character, lo que significa que puede ser a Humano1 o a Humano2 dependiendo del argumento organizacion. En la consulta anterior, solo se puede solicitar campos que existen en la interfaz Character, que no incluye primaryFunction.

Para solicitar un campo en un tipo de objeto específico, debes usar un fragmento en línea, por ejemplo hacemos la siguiente consulta:


Obtenemos los siguientes datos:


Puedes obtener más información sobre esto en la sección de fragmentos en línea en la guía de consulta de la documentación oficial de GraphQL.

Tipos de Unión

Los tipos de unión son muy similares a las interfaces, pero no pueden especificar ningún campo común entre los tipos.


Siempre que devolvamos un tipo ResultadosBusqueda en nuestro esquema, podemos obtener un Humano1, un Humano2 y una Planta. Ten en cuenta que los miembros de un tipo de unión deben ser tipos de objetos concretos; no puedes crear un tipo de unión a partir de interfaces u otras uniones.

En este caso, si consultas un campo que devuelve el tipo de unión ResultadosBusqueda, debes usar un fragmento en línea para poder consultar cualquier campo.

Hacemos la siguiente consulta:


Y obtenemos los siguientes datos:


El campo __typename se resuelve en un String que le permite diferenciar diferentes tipos de datos entre sí en el cliente.

Además, en este caso, dado que Humano1 y Humano2 comparten una interfaz común ( Character), puedes consultar los campos comunes en un solo lugar en lugar de tener que repetir los mismos campos en varios tipos:


Ten en cuenta que nombre todavía se especifica en Organizacion, porque de lo contrario, no aparecería en los resultados dado que Organizacion no es un Character!

Tipos de Entrada

Hasta ahora, solo hemos hablado de pasar valores escalares, como enumeraciones o cadenas, como argumentos en un campo. Pero también puedes pasar fácilmente objetos complejos. Esto es particularmente valioso en el caso de las mutaciones, donde es posible que desees pasar un objeto completo para crearlo. En el lenguaje de esquema de GraphQL, los tipos de entrada tienen exactamente el mismo aspecto que los tipos de objetos normales, pero con la palabra clave input en lugar de type:


Para usar el tipo de objeto de entrada (input) en una mutación, podemos hacer la siguiente consulta:


Obtenemos el siguiente resultado:


Los campos en un tipo de objeto de entrada (input) pueden hacer referencia a tipos de objetos de entrada, pero no puede mezclar tipos de entrada y salida en su esquema. Los tipos de objetos de entrada tampoco pueden tener argumentos en sus campos. Como menciona al inicio de este Post, en otro tutorial, ya sea en el blog o en nuestro canal de YouTube, te enseñaremos a como usar estos tipos de datos, consumiendo los datos de una API REST por ejemplo.

Bien, hasta aqui terminamos con todos los tipos de datos y esquemas que tiene GraphQL.

Conclusión

Conocer los tipos de datos que podemos utilizar en GraphQL, nos servirá de guía para poder consumir y leer datos de por ejemplo una API REST. Al conocer estos tipos de datos, evitaremos los errores en lo posible, que suceden cuando queremos llamar a nuestros datos del servidor.

Nota (s)

  • No olvides que debemos usar la Tecnología para hacer cosas Buenas por el Mundo. 

 

Síguenos en nuestras Redes Sociales para que no te pierdas nuestros próximos contenidos.