GraphQL es un lenguaje de consulta que te permite definir qué datos pedirle a un API. Se trata de una tecnología que Facebook empezó a desarrollar en 2012, aunque fue anunciada en 2015. Según Facebook, proporciona una descripción completa y comprensible de los datos de su API, ofrece a los clientes la posibilidad de pedir exactamente lo que necesitan, facilita la evolución de las API con el paso del tiempo (escalabilidad) y habilita potentes herramientas para desarrolladores.
Uso
// /graphql/index.js// Dependencia que crea un servidorconst{ApolloServer}=require('@apollo/server')// Playground incluido en @apollo/serverconst{ApolloServerPluginLandingPageLocalDefault}=require('@apollo/server/plugin/landingPage/default')// Middleware de Express también en @apollo/serverconst{expressMiddleware}=require('@apollo/server/express4')// Definición de tiposconsttypeDefs=` type Query { hello: String }`// Resolversconstresolvers={Query:{hello:()=>'Hola mundillo'}}constuseGraphQL=async(app)=>{constserver=newApolloServer({typeDefs,resolvers,playground:true,plugins: [ApolloServerPluginLandingPageLocalDefault ]})awaitserver.start()// Uso del middleware en Expressapp.use(expressMiddleware(server,{context:async({req})=> ({token:req.headers.token})}))}module.exports=useGraphQL
En el archivo que inicia el server
typeDefs y los resolvers
En GraphQL, los typeDefs (definiciones de tipos) y los resolvers (resolutores) son dos conceptos fundamentales que trabajan juntos para definir y ejecutar consultas y mutaciones en una API de GraphQL.
typeDefs (Definiciones de Tipos)
Los typeDefs definen la estructura del esquema de GraphQL. Incluyen tipos, consultas, mutaciones y sus respectivos campos. Es esencialmente el "contrato" que especifica qué operaciones están disponibles y qué datos se pueden consultar o modificar.
Resolvers (Resolutores)
Los resolvers son funciones que proporcionan la lógica para obtener los datos definidos en los typeDefs. Cuando se realiza una consulta o mutación, los resolvers son los que realmente "resuelven" la solicitud, ejecutando la lógica necesaria para devolver los datos o realizar cambios.
Ejemplo
Definiendo el Esquema (typeDefs)
Nota: El type def de tipo Query es equivalente al GET y el Mutation es esquvalente al PUT, POST, DELETE y PATCH. El de tipo User no es propio de GraphQL, son propios, es decir, creados de manera personalizada.
Definiendo los Resolutores (resolvers)
En este ejemplo:
typeDefs define los tipos User, las consultas getUser y listUsers, y las mutaciones createUser, updateUser y deleteUser.
resolvers proporciona la lógica para manejar estas consultas y mutaciones, interactuando con una lista de usuarios en memoria (users).
Consultas
En GraphQL todas las consultas son mediante POST accediendo al endpoint expuesto y toda petición retorna 201.
Sistema de tipado
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: El tipo escalar de ID 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.
Nulabilidad y listas
En GraphQL, no define un nuevo tipo cuando intenta devolver una lista de elementos de un campo; simplemente aplica un modificador de lista a ese tipo, así:
Non-null también es un modificador, y resulta que puede aplicar modificadores de listas y no nulos de forma anidada arbitrariamente, especialmente porque las listas se pueden anidar:
Entonces, ¿qué significa tener el no nulo dentro o fuera de una lista? Bueno, decide si el no nulo se aplica al elemento de la lista frente a la lista en sí.
Por ejemplo, puede 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:
Finalmente, podemos combinar los dos:
Este es el más restrictivo:
Una conclusión interesante aquí es que no hay forma de especificar que la lista no puede estar vacía: una lista vacía [ ] siempre es válida, independientemente de si la lista o los elementos no son nulos.