GraphQL vs REST en TypeScript: qué elegir para tu proyecto

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 en TypeScript: ¿duelo de titanes o elección según la tarea?

\n\n

Cuando escribes en TypeScript, la cuestión de la arquitectura del backend se vuelve especialmente crítica. No solo quieres "que funcione", sino que los tipos vuelen, los errores se detecten en tiempo de compilación y el código sea predecible. Y aquí el desarrollador se enfrenta a la elección eterna: ¿el probado REST o el moderno y flexible GraphQL? Ambas tecnologías se llevan muy bien con TypeScript, pero cada una dicta su propio estilo de desarrollo.

\n\n

En este artículo no divagaremos ni contaremos verdades absolutas. Analizaremos GraphQL vs REST en TypeScript con ejemplos concretos, código, puntos débiles y escenarios donde un enfoque supera al otro. ¡Allá vamos!

\n\n

REST: el viejo amigo que nunca falla

\n\n

REST (Transferencia de Estado Representacional) es un estilo arquitectónico donde cada recurso (usuario, publicación, comentario) tiene su propia URL. Accedes a /api/users/1 y obtienes el usuario. Simple y predecible. En proyectos TypeScript, REST se implementa a menudo con Express, Fastify o NestJS.

\n\n

Tipado en REST con TypeScript

\n

El principal dolor de REST es la débil conexión entre el backend y el frontend. Envías JSON y el frontend adivina: "¿Y qué llegó?". TypeScript lo soluciona mediante tipos compartidos o OpenAPI (Swagger).

\n\n

Ejemplo: backend con Express y TypeScript

\n\n
import express, { Request, Response } from 'express';\n\ninterface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\nconst app = express();\napp.get('/api/users/:id', (req: Request, res: Response) => {\n  const user: User = { id: +req.params.id, name: 'Alice', email: 'alice@example.com' };\n  res.json(user);\n});\n
\n\n

Frontend (fetch):

\n\n
interface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\nasync function getUser(id: number): Promise<User> {\n  const res = await fetch(`/api/users/${id}`);\n  return res.json() as Promise<User>;\n}\n
\n\n

Problema: si el backend cambia la estructura de User, el frontend se entera solo en tiempo de ejecución. Los tipos en el frontend son solo una copia. Solución: generar tipos a partir de la especificación OpenAPI.

\n\n

Ventajas de REST en TypeScript

\n
    \n
  • Simplicidad de caché: El caché HTTP (CDN, navegador) funciona de serie.
  • \n
  • Estructura clara: URL = recurso, métodos = acciones (GET, POST, PUT, DELETE).
  • \n
  • Amplio soporte: Cualquier cliente (navegador, curl, Postman) entiende REST.
  • \n
  • Baja barrera de entrada: Incluso un junior lo entenderá en una hora.
  • \n
\n\n

Desventajas de REST

\n
    \n
  • Over-fetching y Under-fetching: O arrastras campos innecesarios o haces varias solicitudes.
  • \n
  • Estructura rígida: Para obtener un usuario + sus publicaciones, necesitas dos solicitudes o parches (campo expand).
  • \n
  • Tipado débil: Sin OpenAPI, los tipos en el cliente son solo "palabra de honor".
  • \n
\n\n

GraphQL: flexibilidad y control

\n\n

GraphQL es un lenguaje de consultas que le da al cliente el derecho de decidir qué datos recibir. Un solo endpoint (/graphql), una sola consulta, y obtienes exactamente lo que pediste. TypeScript y GraphQL son la pareja ideal: los tipos se generan automáticamente a partir del esquema.

\n\n

Tipado en GraphQL con TypeScript

\n

Primero se escribe el esquema (SDL):

\n\n
type User {\n  id: ID!\n  name: String!\n  email: String!\n  posts: [Post!]!\n}\n\ntype Post {\n  id: ID!\n  title: String!\n  content: String!\n}\n\ntype Query {\n  user(id: ID!): User\n}\n
\n\n

Luego se generan los tipos (mediante graphql-codegen):

\n\n
// generated.ts\nexport type User = {\n  __typename?: 'User';\n  id: string;\n  name: string;\n  email: string;\n  posts: Array<Post>;\n};\n\nexport type Post = {\n  __typename?: 'Post';\n  id: string;\n  title: string;\n  content: string;\n};\n

                
                

Blogs

Book Recommendations