Cómo Construir un Servidor API GraphQL con Apollo Server

Ashley Goolam

Ashley Goolam

3 September 2025

Cómo Construir un Servidor API GraphQL con Apollo Server

¿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 excelente herramienta de prueba de API que genere hermosa documentación de API?

¿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**:

mkdir graphql-apollo-server
cd graphql-apollo-server

**Inicializar Node.js**:

npm init -y
npm pkg set type="module"

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
{
  "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
}
package.json

**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.

estructura del proyecto

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.

el playground

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"
  }
}
ejemplo de consulta graphql

¡É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 consulta más complicada

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"
    }
  }
}
probar mutación

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"
      }
    ]
  }
}
libro final añadido

¡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.

añadiendo más complejidad

Mejores prácticas para GraphQL con Apollo Server

Resolución de problemas comunes

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

imagen de apidog

Practica el diseño de API en Apidog

Descubre una forma más fácil de construir y usar APIs