Antes de comenzar me gustaría explicar un poco que es GraphQL; es un lenguaje de manipulación y consulta de datos, está diseñado para estructuras de datos en forma de árboles o jerarquías, facilitando la forma en que consultamos dicha información desde el momento en que realizamos la petición, nosotros podemos establecer que datos queremos y de qué nivel, por ejemplo:

{  user //<-- Tipo  
   {    email, // <-- Atributo    
      name // <-- Atributo  
   }
}

 

La siguiente consulta nos arrojaría una respuesta con el o los usuarios registrados, pero únicamente los atributos de email y name:

{ 
   "data": { 
      "user": { 
         "name": "Juan Manuel Meneses",     
         "email": "jmenesesi@jmenesesi.com",
      } 
   } 
}

Esto se vuelve muy útil cuando necesitamos acceder a cierta información, ya que no nos devolverá datos “basura” que una vez recibidos los desecharemos o ignoraremos (cómo suele suceder al consumir una API Rest).

¿Qué tipo de operaciones hay en GraphQL?

En GraphQL tenemos los Queries o Consultas Ad Hoc y las Mutaciones.

Pero ¿Qué son los Queries? Fácil, un Query lo puedes interpretar como un SELECT de SQL que usamos para obtener datos.

Ok, ¿Entonces que son las Mutaciones? Un Mutation se puede usar para realizar el equivalente a INSERT, UPDATE y DELETE de SQL.

Schemas

En GraphQL al igual que cuando definimos un Payload de un WebService, lo haremos mediante un schema con el diseño de nuestras entidades y mutaciones, las cuales serán accesibles desde el servidor.

A continuación, un ejemplo de un Schema:

const schema = gql`
	type User {
		id: ID!
		name: String!
		email: String!
	}
	type Query {
		users: [User!]
		user(id: ID!): User
	}
`;

Para poder construir correctamente nuestros esquemas es indispensable conocer la siguiente información:

  • Object Types: son las entidades con las que vamos a modelar y estructurar nuestros servicios, en el ejemplo anterior User.
  • Fields: son las propiedades de nuestros Object Types (entidades).
  • Object Type: es una referencia a otro objecto.

Resolvers

Los resolvers son las funciones que se encargarán de responder a las peticiones que hayamos declarado en nuestros Queries, a continuación, el ejemplo de los Resolvers de los Queries declarados anteriormente:

const resolvers = {
  Query: {
	user:(parent, {id}) => {
		return data.users.find(u => u.id === id);
	},
	users: () => {
		return Object.values(data.users);
	}
  },
};

Cómo podemos ver, en los resolver va el cuerpo de los Queries, aquí es donde se podría implementar el llamado a la DB, en este caso solamente se hace el llamado a un JSON declarado anteriormente que contiene un Array de usuarios (users), que mostraré a continuación:

*Nota: Si quieres conocer más al respecto sobre que parámetros puedes o deben recibirse en un resolver, te invito a que consultes la documentación de Apollo (https://www.apollographql.com/docs/apollo-server/essentials/data/).

const data = {
  users: [
	  {
		id: '1',
		name: 'Juan Manuel Meneses',
		email: 'jmenesesi@jmenesesi.com'
	  },
	  {
		id: '2',
		name: 'Rolando Mota del Campo',
		email: 'rmotad@jmenesesi.com'
	  },
  ]
};

Ahora si ya es momento de mostrar la implementación completa de GraphQL, no sin antes mencionar las librerías que se han utilizado para este artículo.

  • apollo-server-express
  • cors
  • express
  • graphql

 

A continuación, el código completo de nuestro index.js:

let express = require('express');
let cors = require('cors');
const { ApolloServer, gql } = require('apollo-server-express');

const app = express();

app.use(cors());

const schema = gql`
	type User {
		id: ID!
		name: String!
		email: String!
	}
	type Query {
		users: [User!]
		user(id: ID!): User
	}
  
`;


const data = {
  users: [
	  {
		id: '1',
		name: 'Juan Manuel Meneses',
		email: 'jmenesesi@jmenesesi.com'
	  },
	  {
		id: '2',
		name: 'Rolando Mota del Campo',
		email: 'rmotad@jmenesesi.com'
	  },
  ]
};

const resolvers = {
  Query: {
	user:(parent, {id}) => {
		return data.users.find(u => u.id === id);
	},
	users: () => {
		return Object.values(data.users);
	}
  },
};

const server = new ApolloServer({
  typeDefs: schema,
  resolvers,
});

server.applyMiddleware({ app, path: '/graphql' });

app.listen({ port: 8000 }, () => {
  console.log('Apollo Server on http://localhost:8000/graphql');
});

*Nota: Recuerda que para inicializar el proyecto e instalar las librerías basta con ejecutar el comando:

npm init --yes

El código lo puedes encontrar en mi repositorio de GitHub (https://github.com/jmenesesi/apollo-server).