Back

Construcción de Clientes API Type-Safe con OpenAPI y TypeScript

Construcción de Clientes API Type-Safe con OpenAPI y TypeScript

Todo desarrollador frontend ha estado ahí: obtienes datos de una API, accedes a un campo que debería existir y obtienes undefined en tiempo de ejecución. Se suponía que TypeScript debía prevenir esto. El problema es que response.json() devuelve any, por lo que el compilador no tiene nada contra qué verificar. Esta guía te muestra cómo solucionar esto correctamente: generando tipos directamente desde tu especificación OpenAPI y usándolos para construir clientes REST type-safe en TypeScript.

Puntos Clave

  • Las interfaces de TypeScript escritas manualmente se desvían de tu API real, creando una falsa sensación de seguridad que conduce a errores en tiempo de ejecución.
  • La generación de código OpenAPI produce tipos directamente desde tu especificación API, manteniendo tu frontend y backend sincronizados.
  • Usa openapi-typescript con openapi-fetch para una configuración ligera basada en fetch, u Orval para hooks generados de TanStack Query y SDKs de cliente completos.
  • Automatiza la generación de tipos en CI o tus scripts de build para que los tipos nunca queden obsoletos.
  • Combina los tipos generados con un validador en tiempo de ejecución como Zod para endpoints críticos donde la seguridad en tiempo de compilación por sí sola no es suficiente.

Por Qué el Tipado Manual Falla

La solución ingenua es escribir interfaces a mano:

// ❌ Compila bien, pero TypeScript simplemente confía en ti
const data = (await response.json()) as User

Esto te da autocompletado, pero se convierte en una mentira en el momento en que el backend cambia. Tus tipos se desvían de la realidad y vuelves a las sorpresas en tiempo de ejecución.

El mejor enfoque: generar tipos desde la fuente de verdad—tu especificación OpenAPI.

El Flujo de Trabajo de Generación de Código TypeScript con OpenAPI

El flujo de trabajo típico se ve así:

  1. Comienza con una especificación OpenAPI (YAML o JSON, alojada o local)
  2. Ejecuta un generador para producir tipos TypeScript o un cliente completo
  3. Importa esos tipos en el código de tu aplicación

Esto mantiene tu frontend sincronizado con el backend automáticamente. Cuando la especificación cambia, regeneras y TypeScript te dice exactamente qué se rompió.

Eligiendo Tu Enfoque: Solo Tipos vs. SDK de Cliente Completo

Hay dos estrategias principales para la generación de código TypeScript con OpenAPI, y la elección correcta depende de tu proyecto.

EnfoqueHerramientasMejor Para
Generar tipos, trae tu propio fetchopenapi-typescript + openapi-fetchProyectos ligeros basados en fetch
Generar un SDK de cliente completoOrval, OpenAPI GeneratorEquipos que desean hooks y clientes listos

La generación solo de tipos mantiene tu bundle pequeño y te permite controlar la capa HTTP. La generación de SDK completo ahorra tiempo de configuración pero añade más código generado para mantener.

OpenAPI 3.0 vs 3.1: La mayoría de las herramientas soportan bien OpenAPI 3.0. El soporte para OpenAPI 3.1 varía—consulta la documentación de tu generador antes de asumir compatibilidad completa.

Enfoque 1: openapi-typescript con openapi-fetch

Este es el camino con runtime mínimo. Genera tipos desde tu especificación, luego usa openapi-fetch como un wrapper delgado y completamente tipado alrededor de la API nativa Fetch.

npx openapi-typescript ./openapi.yaml -o ./src/api/types.ts
npm install openapi-fetch
import createClient from "openapi-fetch"
import type { paths } from "./api/types"

const client = createClient<paths>({ baseUrl: "https://api.example.com" })

// La ruta, parámetros y respuesta están todos verificados por tipos
const { data, error } = await client.GET("/users/{id}", {
  params: { path: { id: 123 } },
})

// TypeScript sabe exactamente cómo se ve `data`
console.log(data?.email)

Los errores tipográficos en rutas, tipos de parámetros incorrectos y formas de respuesta no coincidentes se convierten en errores de compilación. Sobrecarga mínima en runtime y solo una pequeña dependencia en tiempo de ejecución (openapi-fetch).

Enfoque 2: Orval para Generación de Cliente Completo

Orval genera funciones API tipadas y—críticamente—puede generar hooks de TanStack Query directamente desde tu especificación. Esto es útil cuando quieres que la lógica de obtención de datos se maneje por ti.

npm install orval --save-dev

Configura orval.config.ts para apuntar a tu especificación y elige un modo de salida (fetch, axios o react-query). Orval entonces genera funciones como useGetUsers() con seguridad de tipos completa incorporada.

Este enfoque añade más código generado, pero para APIs más grandes reduce significativamente el código repetitivo.

Manteniendo los Tipos Sincronizados

El valor real de la generación de clientes TypeScript con OpenAPI solo se mantiene si regeneras consistentemente. Añade el paso de generación a tu flujo de trabajo de desarrollo:

{
  "scripts": {
    "generate:api": "openapi-typescript ./openapi.yaml -o ./src/api/types.ts"
  }
}

Ejecútalo en CI, o vigila los cambios en la especificación localmente. Algunos equipos hacen commit del archivo generado; otros regeneran en cada build. Cualquiera funciona—solo hazlo automático.

Lo Que Aún Necesitas Manejar

Los tipos generados usualmente proporcionan seguridad solo en tiempo de compilación. La validación en tiempo de ejecución requiere herramientas adicionales como Zod o plugins de generador. Para endpoints críticos, combina tus tipos generados con Zod para validar respuestas en tiempo de ejecución y detectar bugs del backend antes de que lleguen a tu UI.

Conclusión

La generación de código TypeScript con OpenAPI es una de las mejoras de mayor impacto que puedes hacer a una base de código frontend. Elige openapi-typescript con openapi-fetch para una configuración ligera, u Orval si quieres hooks de consulta generados. De cualquier manera, dejas de escribir tipos a mano, dejas de adivinar las formas de respuesta y dejas que el compilador haga el trabajo para el que fue diseñado.

Preguntas Frecuentes

Sí. openapi-typescript soporta tanto especificaciones OpenAPI 3.0 como 3.1, aunque algunas características del schema pueden requerir pruebas con tu generador y especificación específicos. Siempre verifica la salida generada después de actualizar la versión de tu especificación.

Absolutamente. Los tipos generados te dan seguridad en tiempo de compilación, mientras que Zod valida datos en tiempo de ejecución. Puedes definir schemas de Zod que reflejen tus tipos generados y analizar las respuestas de la API a través de ellos. Esto captura casos donde el backend devuelve datos inesperados que el compilador no puede detectar.

Cualquier enfoque funciona. Hacer commit de archivos generados hace que los builds sean más rápidos y te permite revisar cambios de tipos en pull requests. Regenerar en cada build asegura que los tipos siempre estén frescos pero añade una dependencia al paso de build. Elige lo que mejor se ajuste al flujo de trabajo de tu equipo y configuración de CI.

Orval está construido específicamente para TypeScript y genera hooks de TanStack Query, clientes Axios o funciones fetch con configuración mínima. OpenAPI Generator soporta muchos lenguajes pero produce salida TypeScript más verbosa. Para equipos enfocados en frontend, Orval típicamente requiere menos personalización para obtener código limpio e idiomático.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay