GraphQL contra REST: ¿qué tecnología elegir para tu proyecto JavaScript en 2024?

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

GraphQL vs REST: un duelo que debiste empezar ayer

\n\n

¿Te suena esta situación? Estás escribiendo un nuevo proyecto en JavaScript (o Node.js) y de repente surge la pregunta: ¿qué usar para la comunicación entre el frontend y el backend? ¿El clásico REST o el moderno GraphQL? Los debates sobre este tema no cesan, y cada desarrollador tiene su opinión "de hierro".

\n\n

Seamos honestos: REST es ese viejo y buen amigo que nunca te falla. GraphQL es el novato audaz que promete resolver todos tus problemas. Pero, ¿cómo elegir? No te mostraré tablas de comparación aburridas, sino ejemplos reales de combate en JavaScript. Verás cómo se ve el código, dónde surgen los obstáculos y, lo más importante, cuándo usar cada uno.

\n\n

Por cierto, si desarrollas en Python (y este sitio es sobre Python, no lo olvides), los principios para elegir entre estas tecnologías son muy similares. Pero hoy hablamos de JavaScript, el lenguaje que reina tanto en el cliente como en el servidor.

\n\n

Mini curso intensivo: REST y GraphQL en 60 segundos

\n\n

REST (Representational State Transfer)

\n

Es un estilo arquitectónico donde cada recurso (usuario, publicación, comentario) tiene su propia URL. Haces una solicitud GET a /api/users/1 y obtienes el usuario. ¿Quieres sus publicaciones? Ve a /api/users/1/posts. Todo es simple, predecible, pero... a veces demasiado verboso.

\n\n

GraphQL

\n

Es un lenguaje de consultas y un entorno de ejecución. Tienes un único endpoint (generalmente /graphql) y tú decides qué datos quieres obtener. Sin over-fetching (cuando llegan 50 campos y solo necesitas 3) ni under-fetching (cuando necesitas hacer 5 solicitudes para armar una página).

\n\n

Comparación en combate: escribiendo código en JavaScript

\n\n

Imaginemos una tarea típica: mostrar en la página el perfil de un usuario con sus últimas tres publicaciones. Comparemos ambos enfoques.

\n\n

Ejemplo de API REST en Express (Node.js)

\n\n
// Servidor REST en Express\nconst express = require('express');\nconst app = express();\n\napp.get('/api/users/:id', (req, res) => {\n  // Devuelve TODOS los datos del usuario\n  const user = users.find(u => u.id === req.params.id);\n  res.json(user); // { id, name, email, phone, address, ... }\n});\n\napp.get('/api/users/:id/posts', (req, res) => {\n  // Devuelve TODAS las publicaciones del usuario\n  const posts = posts.filter(p => p.userId === req.params.id);\n  res.json(posts); // [{ id, title, body, createdAt, ... }]\n});\n\n// Código del cliente (frontend con fetch)\nasync function loadProfile(userId) {\n  // Primera solicitud: obtenemos el usuario (llega mucha información innecesaria)\n  const userResponse = await fetch(`/api/users/${userId}`);\n  const user = await userResponse.json();\n  \n  // Segunda solicitud: obtenemos las publicaciones (de nuevo datos innecesarios)\n  const postsResponse = await fetch(`/api/users/${userId}/posts`);\n  const allPosts = await postsResponse.json();\n  \n  // Tomamos solo las 3 últimas publicaciones\n  const latestPosts = allPosts.slice(0, 3);\n  \n  return { user, posts: latestPosts };\n}
\n\n

El problema es evidente: obtuvimos muchos datos innecesarios (over-fetching). ¿Para qué necesitamos email, phone, address si solo mostramos el nombre y el avatar? Y puede haber 100 publicaciones, pero solo necesitamos 3.

\n\n

Ejemplo de GraphQL en Apollo Server (Node.js)

\n\n
// Esquema GraphQL\nconst typeDefs = `\n  type User {\n    id: ID!\n    name: String\n    avatar: String\n    posts(limit: Int): [Post]\n  }\n\n  type Post {\n    id: ID!\n    title: String\n    body: String\n  }\n\n  type Query {\n    user(id: ID!): User\n  }\n`;\n\n// Resolvers (lógica de obtención de datos)\nconst resolvers = {\n  Query: {\n    user: (parent, { id }) => users.find(u => u.id === id),\n  },\n  User: {\n    posts: (parent, { limit }) => {\n      let result = posts.filter(p => p.userId === parent.id);\n      if (limit) result = result.slice(0, limit);\n                

Blogs

Book Recommendations