¿Alguna vez te has preguntado cómo crear una **API** potente que permita a los clientes pedir exactamente lo que necesitan? Esa es la magia de **GraphQL**, y con **Apollo Server**, ¡construir una es más sencillo de lo que imaginas! Si estás cansado de los puntos finales rígidos de REST, **GraphQL** ofrece flexibilidad, y **Apollo Server** es la herramienta ideal para lograrlo. En este tutorial conversacional, te guiaremos a través de la configuración de un servidor **GraphQL** usando **Apollo Server**, desde la inicialización del proyecto hasta la prueba de consultas y mutaciones. Ya sea que uses JavaScript o TypeScript, tendrás un servidor funcionando en poco tiempo. ¡Vamos a sumergirnos y construir algo increíble con **GraphQL** y **Apollo Server**!
¿Quieres una plataforma integrada y todo en uno para que tu equipo de desarrolladores trabaje en conjunto con máxima productividad?
Apidog satisface todas tus demandas, y reemplaza a Postman a un precio mucho más asequible!
botón
¿Por qué elegir GraphQL y Apollo Server?
Antes de ponernos manos a la obra, hablemos de por qué **GraphQL** y **Apollo Server** forman un dúo tan dinámico. **GraphQL**, desarrollado por Facebook en 2012 y de código abierto en 2015, es un lenguaje de consulta para APIs que permite a los clientes solicitar datos específicos, reduciendo la sobre-obtención y la sub-obtención comunes en las **APIs REST**. En lugar de múltiples puntos finales, tienes un único punto final inteligente que sirve respuestas personalizadas. Es eficiente, flexible y perfecto para aplicaciones modernas con necesidades de datos complejas.
Presentamos **Apollo Server**, un servidor **GraphQL** de código abierto y gestionado por la comunidad de Apollo GraphQL. Está listo para producción, es compatible con Node.js y se integra perfectamente con bases de datos como MongoDB o PostgreSQL. Con características como la unión de esquemas (schema stitching), el almacenamiento en caché y las suscripciones en tiempo real, es una solución completa para construir APIs escalables. Además, es fácil de usar para principiantes pero potente para profesionales. En comparación con alternativas como Express-GraphQL, **Apollo Server** ofrece una mejor monitorización del rendimiento y una configuración más sencilla. Si estás construyendo un blog, un sitio de comercio electrónico o un backend móvil, esta combinación te ahorrará tiempo y dolores de cabeza. ¿Emocionado? ¡Vamos a configurar nuestro proyecto!
Configuración de tu proyecto en JavaScript o TypeScript
Comencemos creando la base. Configuraremos un proyecto Node.js e instalaremos los paquetes necesarios. Puedes elegir JavaScript por simplicidad o TypeScript por seguridad de tipos; ambos funcionan muy bien con **Apollo Server**.
Paso 1: Inicializar el proyecto
**Crear una nueva carpeta**:
- Abre tu terminal y crea un directorio de proyecto:
mkdir graphql-apollo-server
cd graphql-apollo-server
**Inicializar Node.js**:
- Ejecuta los siguientes comandos:
npm init -y
npm pkg set type="module"
- Esto crea un archivo `package.json` para gestionar las dependencias y configura un proyecto usando Módulos ES.
Paso 2: Instalar dependencias
**Apollo Server** requiere dos paquetes principales: `@apollo/server` para el servidor y `graphql` para la librería central de **GraphQL**. Para TypeScript, añadiremos tipos y un paso de compilación.
**Instalar dependencias:**
npm install @apollo/server graphql
**Para JavaScript**:
Simplemente reemplaza la entrada `scripts` predeterminada en tu archivo `package.json` con estas entradas `type` y `scripts`:
{
// ...etc.
"type": "module",
"scripts": {
"start": "node index.js"
}
// other dependencies
}
**Para TypeScript (Recomendado)**:
1. Inicializar TypeScript:
npm install --save-dev typescript @types/node
- Crea un archivo `tsconfig.json` en tu directorio raíz y edítalo para incluir:
{
"compilerOptions": {
"rootDirs": ["src"],
"outDir": "dist",
"lib": ["es2023"],
"target": "es2023",
"module": "esnext",
"moduleResolution": "node",
"esModuleInterop": true,
"types": ["node"]
}
}
2. Finalmente, reemplaza la entrada `scripts` en tu archivo `package.json` con las siguientes entradas `type` y `scripts`:
{
// ...etc.
"type": "module",
"scripts": {
"compile": "tsc",
"start": "npm run compile && node ./dist/index.js"
}
// other dependencies
}

**Consejo profesional**: Si eres nuevo en TypeScript, añade seguridad de tipos a tu esquema y resolutores, detectando errores tempranamente. JavaScript es más rápido para prototipos; elige según la escala de tu proyecto.
Paso 3: Crear el archivo del servidor
Crea una carpeta `src` en la raíz de tu proyecto y añade un archivo `index.ts` (o `index.js` para JavaScript) en la nueva carpeta. Aquí es donde definiremos el esquema y los resolutores.

Probando una consulta simple
Vamos a construir nuestra primera consulta: un simple mensaje de "hola". Esto introduce las definiciones de tipos (esquema) de **GraphQL** y los resolutores (funciones que obtienen datos).
Definir el esquema GraphQL
El esquema es el plano de tu API. Usa la etiqueta `gql` de `graphql-tag` (incluida con `@apollo/server`) para definirlo.
En `index.ts` (o `index.js`):
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
// Define GraphQL schema
const typeDefs = `
type Query {
hello: String
}
`;
// Define resolvers
const resolvers = {
Query: {
hello: () => "Hello! Welcome to my server",
},
};
// Create and start the server
const server = new ApolloServer({ typeDefs, resolvers });
const { url } = await startStandaloneServer(server, {
listen: { port: 4000 },
});
console.log(`🚀 Server ready at: ${url}`);
Para JavaScript, importa los tipos:
const { ApolloServer } = '@apollo/server';
const { startStandaloneServer } = '@apollo/server/standalone';
// Rest is the same
Ejecutar el servidor
Inicia tu servidor:
node index.js # For JavaScript
npm start # For TypeScript
Visita `http://localhost:4000` en tu navegador. Verás el GraphQL Playground, un IDE basado en web para probar consultas.

Probar la consulta
En el Playground, ejecuta esta consulta en el panel izquierdo:
query {
hello
}
Haz clic en "Ejecutar". A la derecha, verás:
{
"data": {
"hello": "Hello! Welcome to my server"
}
}

¡Éxito! Esta consulta simple demuestra los fundamentos de **GraphQL**: un tipo `Query` con un campo `hello` que devuelve una cadena. Los resolutores son los "cerebros" que proporcionan los datos, en este caso, un mensaje estático. Es un excelente punto de partida para verificar tu configuración.
Probando una consulta con un tipo complejo
Ahora, vamos a añadir algo de profundidad con un tipo personalizado. Crearemos un tipo `Book` y una consulta para obtener una lista de libros. Esto muestra cómo **GraphQL** maneja los datos estructurados.
Actualizar el esquema
Modifica `typeDefs` para incluir un tipo `Book`:
const typeDefs = gql`
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
`;
Añadir datos de ejemplo
Debajo de `typeDefs` añade los siguientes datos de ejemplo para nuestro nuevo tipo `Book`:
// Sample data
const books = [
{
title: 'The Awakening',
author: 'Kate Chopin',
},
{
title: 'City of Glass',
author: 'Paul Auster',
},
];
Actualizar resolutores
Reemplaza el contenido del resolutor con lo siguiente para el tipo `books`:
const resolvers = {
Query: {
books: () => books
}
};
Reinicia el servidor y vuelve al Playground.
Probar la consulta
Ejecuta:
query GetBooks {
books {
title
author
}
}
Resultado:
{
"data": {
"books": [
{
"title": "The Awakening",
"author": "Kate Chopin"
},
{
"title": "City of Glass",
"author": "Paul Auster"
}
]
}
}
Genial, ¿verdad? Esta consulta obtiene un array de objetos `Book`. **GraphQL** permite a los clientes especificar exactamente qué campos quieren, ni más ni menos. Si omites `author`, solo devolverá los títulos. Esta flexibilidad es la razón por la que **GraphQL** supera a REST para aplicaciones con muchos datos.

Probando una mutación para añadir datos
Las consultas son para leer, pero las mutaciones son para escribir. Vamos a añadir una mutación para crear un nuevo libro, demostrando cómo **GraphQL** maneja la creación de datos.
Actualizar el esquema
Añade un tipo `Mutation`:
const typeDefs = `
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
type Mutation {
createBook(title: String!, author: String!): Book
}
`;
El `!` significa campos obligatorios.
Actualizar resolutores
const resolvers = {
Query: {
books: () => books,
},
Mutation: {
createBook: (_: any, { title, author }: { title: string; author: string }) => {
const newBook = { title, author };
books.push(newBook);
return newBook;
}
}
};
Probar la mutación
En el Playground, ejecuta:
mutation CreateBook{
createBook(title: "Harry Potter", author: "J.K Rowling") {
author
title
}
}
Resultado:
{
"data": {
"createBook": {
"title": "Harry Potter",
"author": "J.K Rowling"
}
}
}

Para confirmar, vuelve a ejecutar la consulta `GetBooks`:
query GetBooks {
books {
title
author
}
}
Resultado:
{
"data": {
"books": [
{
"title": "The Awakening",
"author": "Kate Chopin"
},
{
"title": "City of Glass",
"author": "Paul Auster"
},
{
"title": "Harry Potter",
"author": "J.K Rowling"
}
]
}
}

¡El nuevo libro ha sido añadido! Las mutaciones devuelven los datos creados, permitiendo a los clientes obtener una retroalimentación inmediata. En producción, conéctate a una base de datos como MongoDB para la persistencia.
**JavaScript vs TypeScript: ¿Cuál elegir?** Para prototipos rápidos, JavaScript está bien, con menos código repetitivo. Pero para proyectos más grandes, TypeScript brilla con la seguridad de tipos para esquemas y resolutores. TS detecta errores tempranamente, haciendo que tu servidor **GraphQL** sea más robusto.
Añadiendo más complejidad: IDs y consultas con argumentos
Para hacerlo más real, añade IDs a los libros y una consulta para buscar por título.
Actualizar esquema:
const typeDefs = `
type Book {
id: ID!
title: String
author: String
}
type Query {
books: [Book]
book(title: String!): Book
}
type Mutation {
createBook(title: String!, author: String!): Book
}
`;
Actualizar datos y resolutores:
// Sample data
const books = [
{
id: 1,
title: 'The Awakening',
author: 'Kate Chopin',
},
{
id: 2,
title: 'City of Glass',
author: 'Paul Auster',
},
];
// Resolvers
const resolvers = {
Query: {
books: () => books,
book: (_: any, { title }: { title: string }) => books.find(book => book.title === title),
},
Mutation: {
createBook: (_: any, { title, author }: { title: string; author: string }) => {
const newBook = { id: books.length + 1, title, author };
books.push(newBook);
return newBook;
}
}
};
Probar la consulta:
query GetBook {
book(title: "The Awakening") {
id
title
author
}
}
Resultado:
{
"data": {
"book": {
"id": "1",
"title": "The Awakening",
"author": "Kate Chopin"
}
}
}
Esto muestra argumentos en las consultas, permitiendo a los clientes filtrar datos de manera eficiente.

Mejores prácticas para GraphQL con Apollo Server
- **Diseño de esquemas**: Mantenlo modular con múltiples archivos.
- **Manejo de errores**: Usa `ApolloError` para errores personalizados.
- **Rendimiento**: Habilita el almacenamiento en caché con `@apollo/cache-control`.
- **Suscripciones**: Añade tiempo real con `apollo-server-express`.
- **Monitorización**: Usa Apollo Studio para métricas.
Resolución de problemas comunes
- **¿El servidor no arranca?** Verifica la versión de Node (14+) y las dependencias.
- **¿Errores de consulta?** Verifica la coincidencia del esquema/resolutor.
- **¿Problemas de CORS?** Añade `{ cors: { origin: '*' } }` a las opciones del servidor.
- **¿Errores de TS?** Instala `@types/graphql` y `@types/node`.
Conclusión
Hemos construido un servidor **GraphQL** robusto con **Apollo Server**, desde consultas "hello" hasta mutaciones. Ya sea en JS o TS, estás listo para crear APIs flexibles. Experimenta, añade suscripciones y despliega en Heroku. ¡**GraphQL** y **Apollo Server** son tu boleto para APIs eficientes!
¡**Apidog** también soporta pruebas con GraphQL, así que asegúrate de probarlo completamente **GRATIS**!
botón
