Introducción: API — no son solo solicitudes, es un diálogo
Hace tiempo, en la era de los monolitos, los desarrolladores escribían backend en PHP o Java, y el frontend simplemente llamaba a URLs predefinidas. Todo era simple, pero lento. Hoy, el ecosistema de TypeScript dicta nuevas reglas: no solo queremos intercambiar datos, sino hacerlo de forma segura, estricta y con autocompletado. Aquí es donde entran en juego tres gigantes: REST, GraphQL y gRPC.
En este artículo no vamos a repetir la documentación. Revisaremos cada protocolo desde la perspectiva de un profesional en TypeScript: veremos ejemplos de código reales, compararemos el rendimiento y entenderemos qué herramienta es adecuada para tu proyecto. Si escribes en TypeScript y quieres mejorar tus habilidades con API, estás en el lugar correcto.
API REST en TypeScript: un clásico que nunca muere
REST (Transferencia de Estado Representacional) es el estándar de facto. Simplicidad, métodos HTTP (GET, POST, PUT, DELETE) y recursos. Pero en TypeScript, REST se revela de una nueva manera: obtenemos un tipado estricto para solicitudes y respuestas.
Cómo se ve un cliente REST tipado
Escribamos un cliente mínimo pero funcional para una API REST en TypeScript. Sin librerías adicionales, solo fetch y tipos.
// Tipos para la respuestainterface User { id: number; name: string; email: string;}
interface ApiResponse<T> { data: T; status: number; message: string;}
// Cliente tipadoclass RestClient { private baseUrl: string;
constructor(baseUrl: string) { this.baseUrl = baseUrl; }
async get<T>(endpoint: string): Promise<ApiResponse<T>> { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'GET', headers: { 'Content-Type': 'application/json' }, });
if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); }
const data: T = await response.json(); return { data, status: response.status, message: 'Success', }; }
async post<T, U>(endpoint: string, body: U): Promise<ApiResponse<T>> { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), });
if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); }
const data: T = await response.json(); return { data, status: response.status, message: 'Created', }; }}
// Usoconst client = new RestClient('https://jsonplaceholder.typicode.com');
async function fetchUser() { const response = await client.get<User>('/users/1'); console.log(response.data.name); // ¡El autocompletado funciona!}
fetchUser();Como puedes ver, la API REST en TypeScript nos da control sobre los tipos en cada paso. ¿Un error en el nombre del campo? TypeScript lo detectará en tiempo de compilación.
Cuándo elegir REST
- Simplicidad — REST es fácil de entender y mantener.
- Almacenamiento en caché — el caché HTTP funciona de serie.
- Aplicaciones CRUD — blogs, tiendas, paneles de administración.
Desventaja: con consultas anidadas complejas, obtienes muchos datos (over-fetching) o haces N consultas (problema N+1).
GraphQL en TypeScript: flexibilidad y precisión
GraphQL es un lenguaje de consultas creado por Facebook. Su principal característica: tú decides qué campos obtener. GraphQL en TypeScript es un poderoso tándem que proporciona total seguridad de tipos tanto en el cliente como en el servidor.
Escribiendo una consulta GraphQL con tipado
Para el ejemplo, usaremos la librería graphql-request, un cliente ligero para TypeScript.
import { request, gql } from 'grap