OpenAPI (alfa)
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Este paquete está en fase alfa. Las API pueden cambiar sin previo aviso.
El paquete @trpc/openapi genera una especificación OpenAPI 3.1 desde tu router tRPC. Utiliza el spec para:
-
Generar un cliente API con tipado seguro en cualquier lenguaje
-
Llamar a endpoints tRPC mediante herramientas HTTP como Postman o Insomnia
-
Habilitar integraciones con agentes de IA como servidores MCP
Instalación
bashpnpm add @trpc/openapi
bashpnpm add @trpc/openapi
Si utilizas un agente de IA para programación, instala habilidades de tRPC para una mejor generación de código:
bashnpx @tanstack/intent@latest install
bashnpx @tanstack/intent@latest install
@trpc/openapi actualmente tiene versiones como 11.x.x-alfa, y debería funcionar con cualquier versión reciente de tRPC v11, pero como siempre recomendamos alinear los números de versión
Adaptando tu configuración tRPC
El generador funciona con tu router existente — no se requieren anotaciones ni decoradores. Algunos aspectos a considerar:
-
No necesitas tipos de salida — a diferencia de otras herramientas OpenAPI, los esquemas
.output()son opcionales. El generador infiere los tipos de retorno automáticamente desde tu implementación. -
Transformers — si tu servidor usa un data transformer, tus clientes OpenAPI deben usar el mismo. Consulta Transformers para opciones de configuración y uso entre lenguajes.
-
Suscripciones — actualmente excluidas del spec generado. Se planea soporte para SSE (Server-Sent Events).
-
Descripciones — las llamadas
.describe()de Zod y los comentarios JSDoc en tipos, routers y procedimientos se convierten en camposdescriptionen el spec.
Generar el spec
CLI
bashpnpm exec trpc-openapi ./src/server/router.ts
bashpnpm exec trpc-openapi ./src/server/router.ts
| Option | Default | Description |
|---|---|---|
-e, --export <name> | AppRouter | Name of the exported router type |
-o, --output <file> | openapi.json | Output file path |
--title <text> | tRPC API | OpenAPI info.title |
--version <ver> | 0.0.0 | OpenAPI info.version |
bashpnpm exec trpc-openapi ./src/server/router.ts -o api.json --title "My API" --version 1.0.0
bashpnpm exec trpc-openapi ./src/server/router.ts -o api.json --title "My API" --version 1.0.0
Programático
scripts/generate-openapi.tstsimport { generateOpenAPIDocument } from '@trpc/openapi';const doc = generateOpenAPIDocument('./src/server/router.ts', {exportName: 'AppRouter',title: 'My API',version: '1.0.0',});
scripts/generate-openapi.tstsimport { generateOpenAPIDocument } from '@trpc/openapi';const doc = generateOpenAPIDocument('./src/server/router.ts', {exportName: 'AppRouter',title: 'My API',version: '1.0.0',});
El generador analiza estáticamente los tipos TypeScript de tu router — nunca ejecuta tu código.
Generar un cliente desde el spec
Cualquier generador de clientes OpenAPI debería funcionar, pero la integración más probada es con Hey API.
Un cliente generado producirá funciones SDK tipadas que coinciden con tus procedimientos tRPC:
-
Consultas →
GET /procedure.path -
Mutaciones →
POST /procedure.path -
Subscriptions se ignoran (SSE próximamente)
Hey API (TypeScript)
bashpnpm add @trpc/openapi @hey-api/openapi-ts
bashpnpm add @trpc/openapi @hey-api/openapi-ts
Por defecto, un cliente generado por OpenAPI no conocerá tu configuración de transformer ni cómo codificar parámetros de consulta. El paquete @trpc/openapi/heyapi provee un helper configureTRPCHeyApiClient que cubre este vacío — configura la serialización de solicitudes, el análisis de respuestas y la deserialización de errores para que el SDK generado funcione correctamente con endpoints tRPC.
Sin transformer
Puedes generar tu cliente usando la CLI de Hey API o su API programática en este caso
bashpnpm exec openapi-ts -i openapi.json -o ./generated
bashpnpm exec openapi-ts -i openapi.json -o ./generated
Luego se requiere un poco de configuración en tiempo de ejecución:
src/usage.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import { client } from './generated/client.gen';import { Sdk } from './generated/sdk.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',});const sdk = new Sdk({ client });const result = await sdk.greeting({ query: { input: { name: 'World' } } });const user = await sdk.user.create({ body: { name: 'Bob', age: 30 } });
src/usage.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import { client } from './generated/client.gen';import { Sdk } from './generated/sdk.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',});const sdk = new Sdk({ client });const result = await sdk.greeting({ query: { input: { name: 'World' } } });const user = await sdk.user.create({ body: { name: 'Bob', age: 30 } });
Con transformer (superjson, devalue, etc.)
Si tu backend usa un data transformer como superjson, debes pasarlo a la configuración del cliente. Sin esto, fechas, mapas, conjuntos y otros tipos no JSON pueden ser incorrectos silenciosamente.
Primero genera tu código cliente usando la API programática de Hey API, así puedes usar createTRPCHeyApiTypeResolvers para garantizar que tus tipos emitidos sean correctos:
src/client.tstsimport { createClient } from '@hey-api/openapi-ts';import { createTRPCHeyApiTypeResolvers } from '@trpc/openapi/heyapi';const openApiJson = './path/to/openapi.json'const outputDir = './generated'await createClient({input: openApiJson,output: outputDir,plugins: [{name: '@hey-api/typescript',// Important: this ensures that your emitted types like Dates are correct'~resolvers': createTRPCHeyApiTypeResolvers(),},{name: '@hey-api/sdk',operations: { strategy: 'single' },},],});
src/client.tstsimport { createClient } from '@hey-api/openapi-ts';import { createTRPCHeyApiTypeResolvers } from '@trpc/openapi/heyapi';const openApiJson = './path/to/openapi.json'const outputDir = './generated'await createClient({input: openApiJson,output: outputDir,plugins: [{name: '@hey-api/typescript',// Important: this ensures that your emitted types like Dates are correct'~resolvers': createTRPCHeyApiTypeResolvers(),},{name: '@hey-api/sdk',operations: { strategy: 'single' },},],});
En tiempo de ejecución configura el cliente generado con tu transformer. Luego puedes pasar tipos nativos directamente y recibirlos deserializados:
src/usage.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import superjson from 'superjson';import { client } from './generated/client.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',// Important, this transformer must match your tRPC API's transformer:transformer: superjson,});const sdk = new Sdk({ client });const event = await sdk.getEvent({query: { input: { id: 'evt_1', at: new Date('2025-06-15T10:00:00Z') } },});// event.data.result.data.at is a Date object ✅const created = await sdk.createEvent({body: { name: 'Conference', at: new Date('2025-09-01T09:00:00Z') },});
src/usage.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import superjson from 'superjson';import { client } from './generated/client.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',// Important, this transformer must match your tRPC API's transformer:transformer: superjson,});const sdk = new Sdk({ client });const event = await sdk.getEvent({query: { input: { id: 'evt_1', at: new Date('2025-06-15T10:00:00Z') } },});// event.data.result.data.at is a Date object ✅const created = await sdk.createEvent({body: { name: 'Conference', at: new Date('2025-09-01T09:00:00Z') },});
Usando un generador o lenguaje diferente
La especificación OpenAPI generada funciona con cualquier generador de clientes compatible con OpenAPI que pueda:
-
Emitir tipos precisos para clases como Date
-
Soportar personalización de parámetros de búsqueda y serialización del cuerpo de solicitudes/respuestas
Para integrarse correctamente con el protocolo de tRPC, debes configurar tu cliente generado para hacer dos cosas:
-
Transformadores — Si tu API de tRPC usa un transformador, el cliente debe serializar inputs y deserializar outputs usando el mismo formato
-
Inputs de consultas — Las solicitudes GET codifican el input como
?input=<JSON>, no como parámetros de consulta individuales
Consulta la configuración de Hey API para ver una implementación de referencia completa.
Transformadores
Los transformadores de datos de tRPC permiten enviar tipos complejos como Date, Map, Set y BigInt a través de la red. Al usar el cliente OpenAPI, el mismo transformador debe configurarse tanto en el servidor como en el cliente para que los inputs se serialicen y los outputs se deserialicen correctamente.
Cualquier transformador que implemente la interfaz DataTransformer de tRPC (serialize / deserialize) funciona con configureTRPCHeyApiClient. A continuación algunas opciones probadas.
SuperJSON
El transformador más popular para configuraciones TypeScript-to-TypeScript. Maneja Date, Map, Set, BigInt, RegExp y más.
bashpnpm add superjson
bashpnpm add superjson
src/server.tstsimport { initTRPC } from '@trpc/server';import superjson from 'superjson';const t = initTRPC.create({ transformer: superjson });
src/server.tstsimport { initTRPC } from '@trpc/server';import superjson from 'superjson';const t = initTRPC.create({ transformer: superjson });
src/client.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import superjson from 'superjson';import { client } from './generated/client.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',transformer: superjson,});
src/client.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import superjson from 'superjson';import { client } from './generated/client.gen';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',transformer: superjson,});
Consulta la prueba de superjson para ver un ejemplo completo de extremo a extremo.
MongoDB Extended JSON v2
EJSON es una buena opción cuando necesitas soporte multiplataforma. El paquete npm bson proporciona EJSON.serialize / EJSON.deserialize que se mapean directamente a un DataTransformer de tRPC.
Disponible en: C, C#, C++, Go, Java, Node.js, Perl, PHP, Python, Ruby, Scala
bashpnpm add bson
bashpnpm add bson
src/transformer.tstsimport { EJSON } from 'bson';import type { TRPCDataTransformer } from '@trpc/server';export const ejsonTransformer: TRPCDataTransformer = {serialize: (value) => EJSON.serialize(value),deserialize: (value) => EJSON.deserialize(value as Document),};
src/transformer.tstsimport { EJSON } from 'bson';import type { TRPCDataTransformer } from '@trpc/server';export const ejsonTransformer: TRPCDataTransformer = {serialize: (value) => EJSON.serialize(value),deserialize: (value) => EJSON.deserialize(value as Document),};
src/client.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import { client } from './generated/client.gen';import { ejsonTransformer } from './transformer';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',transformer: ejsonTransformer,});
src/client.tstsimport { configureTRPCHeyApiClient } from '@trpc/openapi/heyapi';import { client } from './generated/client.gen';import { ejsonTransformer } from './transformer';configureTRPCHeyApiClient(client, {baseUrl: 'http://localhost:3000',transformer: ejsonTransformer,});
Consulta la prueba de MongoDB EJSON para ver un ejemplo completo de extremo a extremo.
Amazon Ion
Amazon Ion es un formato de datos con tipos complejos y amplio soporte de lenguajes. No implementa directamente la interfaz TRPCDataTransformer y requiere código adicional para funcionar con tRPC en JS/TS, pero puede ser una buena opción para sistemas personalizados.
Disponible en: C, C#, D, Go, Java, JavaScript, PHP, Python, Rust
bashpnpm add ion-js
bashpnpm add ion-js
Consulta la prueba de Amazon Ion para ver la implementación del transformador, código adicional y un ejemplo completo de extremo a extremo.
Crear un transformador personalizado
Cualquier objeto con métodos serialize y deserialize funciona:
tsimport type { TRPCDataTransformer } from '@trpc/server';const myTransformer: TRPCDataTransformer = {serialize: (value) => {/* encode rich types */},deserialize: (value) => {/* decode them back */},};
tsimport type { TRPCDataTransformer } from '@trpc/server';const myTransformer: TRPCDataTransformer = {serialize: (value) => {/* encode rich types */},deserialize: (value) => {/* decode them back */},};
Pásalo tanto a initTRPC.create({ transformer }) en el servidor como a configureTRPCHeyApiClient(client, { transformer }) en el cliente. Consulta la documentación de transformadores de datos para más detalles.
Ejemplo completo
Para un proyecto ejecutable que integra todos estos pasos, consulta el ejemplo openapi-codegen.