Introducción a GraphQL

GraphQL es un lenguaje de consulta para APIs y un entorno de ejecución para realizar esas consultas con tus datos existentes. Fue desarrollado internamente por Facebook en 2012 y lanzado públicamente en 2015. A diferencia de REST, donde tienes múltiples endpoints para diferentes recursos, con GraphQL tienes un único endpoint que te permite solicitar exactamente los datos que necesitas.

Ventajas de GraphQL

  • Consulta precisa: Permite a los clientes solicitar exactamente los datos que necesitan.
  • Menos solicitudes: Reduce el número de solicitudes HTTP necesarias.
  • Evolución de la API: Facilita la evolución de la API sin afectar a los clientes existentes.
  • Tipado fuerte: Utiliza un sistema de tipos para definir la estructura de la API.

Configuración del Entorno

Para empezar a usar GraphQL con Node.js, necesitas configurar tu entorno. Vamos a utilizar Express.js y Apollo Server para este propósito.

Instalación de Dependencias

Primero, crea un nuevo proyecto de Node.js y navega a su directorio:

mkdir graphql-nodejs
cd graphql-nodejs
npm init -y

Luego, instala las dependencias necesarias:

npm install express apollo-server-express graphql

Configuración de Apollo Server con Express

Crea un archivo index.js y configura Apollo Server con Express:

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

// Definición del esquema
const typeDefs = gql`
  type Query {
    hello: String
  }
`;

// Definición de los resolvers
const resolvers = {
  Query: {
    hello: () => '¡Hola, mundo!',
  },
};

// Creación del servidor Apollo
const server = new ApolloServer({ typeDefs, resolvers });

const app = express();
server.applyMiddleware({ app });

// Iniciar el servidor
app.listen({ port: 4000 }, () =>
  console.log(`🚀 Servidor listo en http://localhost:4000${server.graphqlPath}`)
);

Explicación del Código

  1. Definición del Esquema: Utilizamos el lenguaje de esquema de GraphQL para definir un tipo Query con un campo hello que devuelve una cadena.
  2. Definición de los Resolvers: Los resolvers son funciones que resuelven las consultas definidas en el esquema. En este caso, el resolver para hello devuelve la cadena '¡Hola, mundo!'.
  3. Creación del Servidor Apollo: Creamos una instancia de ApolloServer pasando el esquema y los resolvers.
  4. Integración con Express: Aplicamos el middleware de Apollo Server a la aplicación Express.
  5. Inicio del Servidor: Iniciamos el servidor en el puerto 4000 y mostramos un mensaje en la consola.

Consultas y Mutaciones

Definición de Tipos y Consultas

Vamos a extender nuestro esquema para incluir más tipos y consultas. Supongamos que estamos construyendo una API para gestionar libros y autores.

const typeDefs = gql`
  type Book {
    title: String
    author: Author
  }

  type Author {
    name: String
    books: [Book]
  }

  type Query {
    books: [Book]
    authors: [Author]
  }
`;

const books = [
  { title: 'El Quijote', author: { name: 'Miguel de Cervantes' } },
  { title: 'Cien Años de Soledad', author: { name: 'Gabriel García Márquez' } },
];

const authors = [
  { name: 'Miguel de Cervantes', books: [{ title: 'El Quijote' }] },
  { name: 'Gabriel García Márquez', books: [{ title: 'Cien Años de Soledad' }] },
];

const resolvers = {
  Query: {
    books: () => books,
    authors: () => authors,
  },
};

Ejemplo de Consulta

Con el esquema y los resolvers definidos, puedes realizar consultas como la siguiente:

{
  books {
    title
    author {
      name
    }
  }
}

Esta consulta devolverá una lista de libros con sus respectivos autores.

Definición de Mutaciones

Las mutaciones en GraphQL permiten modificar datos. Vamos a añadir una mutación para agregar un nuevo libro.

const typeDefs = gql`
  type Book {
    title: String
    author: Author
  }

  type Author {
    name: String
    books: [Book]
  }

  type Query {
    books: [Book]
    authors: [Author]
  }

  type Mutation {
    addBook(title: String, authorName: String): Book
  }
`;

const resolvers = {
  Query: {
    books: () => books,
    authors: () => authors,
  },
  Mutation: {
    addBook: (_, { title, authorName }) => {
      const newBook = { title, author: { name: authorName } };
      books.push(newBook);
      return newBook;
    },
  },
};

Ejemplo de Mutación

Puedes realizar la siguiente mutación para agregar un nuevo libro:

mutation {
  addBook(title: "Don Quijote", authorName: "Miguel de Cervantes") {
    title
    author {
      name
    }
  }
}

Ejercicio Práctico

Ejercicio

  1. Objetivo: Extender la API para incluir un tipo Publisher y permitir la adición de nuevos editores.
  2. Pasos:
    • Añadir el tipo Publisher al esquema.
    • Añadir una consulta para obtener todos los editores.
    • Añadir una mutación para agregar un nuevo editor.

Solución

const typeDefs = gql`
  type Book {
    title: String
    author: Author
    publisher: Publisher
  }

  type Author {
    name: String
    books: [Book]
  }

  type Publisher {
    name: String
    books: [Book]
  }

  type Query {
    books: [Book]
    authors: [Author]
    publishers: [Publisher]
  }

  type Mutation {
    addBook(title: String, authorName: String, publisherName: String): Book
    addPublisher(name: String): Publisher
  }
`;

const publishers = [
  { name: 'Editorial Planeta', books: [] },
  { name: 'Penguin Random House', books: [] },
];

const resolvers = {
  Query: {
    books: () => books,
    authors: () => authors,
    publishers: () => publishers,
  },
  Mutation: {
    addBook: (_, { title, authorName, publisherName }) => {
      const newBook = { title, author: { name: authorName }, publisher: { name: publisherName } };
      books.push(newBook);
      return newBook;
    },
    addPublisher: (_, { name }) => {
      const newPublisher = { name, books: [] };
      publishers.push(newPublisher);
      return newPublisher;
    },
  },
};

Ejemplo de Consulta y Mutación

Consulta para obtener todos los editores:

{
  publishers {
    name
    books {
      title
    }
  }
}

Mutación para agregar un nuevo editor:

mutation {
  addPublisher(name: "HarperCollins") {
    name
  }
}

Conclusión

En esta sección, hemos aprendido los conceptos básicos de GraphQL y cómo integrarlo con Node.js utilizando Apollo Server y Express. Hemos cubierto la definición de esquemas, consultas, mutaciones y cómo extender la API para incluir nuevos tipos. Con estos conocimientos, estás preparado para construir APIs más eficientes y flexibles utilizando GraphQL.

En el siguiente módulo, exploraremos cómo desplegar aplicaciones Node.js y gestionar el entorno de producción. ¡Sigue adelante!

Curso de Node.js

Módulo 1: Introducción a Node.js

Módulo 2: Conceptos Básicos

Módulo 3: Sistema de Archivos y E/S

Módulo 4: HTTP y Servidores Web

Módulo 5: NPM y Gestión de Paquetes

Módulo 6: Framework Express.js

Módulo 7: Bases de Datos y ORMs

Módulo 8: Autenticación y Autorización

Módulo 9: Pruebas y Depuración

Módulo 10: Temas Avanzados

Módulo 11: Despliegue y DevOps

Módulo 12: Proyectos del Mundo Real

© Copyright 2024. Todos los derechos reservados