OpenAPI (alpha)
Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →
Ce package est en phase alpha. Les API peuvent changer sans préavis.
Le package @trpc/openapi génère une spécification OpenAPI 3.1 à partir de votre routeur tRPC. Utilisez cette spécification pour :
-
Générer un client API typé dans n'importe quel langage
-
Appeler les endpoints tRPC via des outils HTTP comme Postman ou Insomnia
-
Activer des intégrations d'agents IA comme les serveurs MCP
Installation
bashpnpm add @trpc/openapi
bashpnpm add @trpc/openapi
Si vous utilisez un agent de codage IA, installez les compétences tRPC pour une meilleure génération de code :
bashnpx @tanstack/intent@latest install
bashnpx @tanstack/intent@latest install
@trpc/openapi est actuellement versionné en 11.x.x-alpha et devrait fonctionner avec n'importe quelle version récente de tRPC v11, mais comme toujours, nous recommandons d'aligner les numéros de version.
Adapter votre configuration tRPC
Le générateur fonctionne avec votre routeur existant — aucune annotation ou décorateur n'est requis. Quelques points à connaître :
-
Aucun schéma de sortie requis — contrairement à d'autres outils OpenAPI, les schémas
.output()sont optionnels. Le générateur déduit automatiquement les types de retour de votre implémentation. -
Transformateurs — si votre serveur utilise un transformateur de données, vos clients OpenAPI doivent utiliser le même. Voir Transformateurs pour les options de configuration et interlangages.
-
Abonnements — actuellement exclus de la spécification générée. La prise en charge SSE est prévue.
-
Descriptions — les appels Zod
.describe()et les commentaires JSDoc sur les types, routeurs et procédures deviennent tous des champsdescriptiondans la spécification.
Générer la spécification
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
Programmatique
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',});
Le générateur analyse statiquement les types TypeScript de votre routeur — il n'exécute jamais votre code.
Générer un client à partir de la spécification
N'importe quel générateur de client OpenAPI devrait fonctionner, mais l'intégration la plus testée est avec Hey API.
Un client généré produira des fonctions SDK typées correspondant à vos procédures tRPC :
-
Requêtes →
GET /procedure.path -
Mutations →
POST /procedure.path -
Abonnements ignorés (SSE à venir)
Hey API (TypeScript)
bashpnpm add @trpc/openapi @hey-api/openapi-ts
bashpnpm add @trpc/openapi @hey-api/openapi-ts
Par défaut, un client généré via OpenAPI ne connaîtra pas votre configuration de transformateur ni comment encoder les paramètres de requête. Le package @trpc/openapi/heyapi fournit un helper configureTRPCHeyApiClient qui comble cette lacune — il configure la sérialisation des requêtes, l'analyse des réponses et la désérialisation des erreurs pour que le SDK généré fonctionne correctement avec les endpoints tRPC.
Sans transformateur
Vous pouvez générer votre client en utilisant la CLI ou l'API programmatique de Hey API dans ce cas.
bashpnpm exec openapi-ts -i openapi.json -o ./generated
bashpnpm exec openapi-ts -i openapi.json -o ./generated
Ensuite, une petite configuration est nécessaire au runtime :
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 } });
Avec transformateur (superjson, devalue, etc.)
Si votre backend utilise un transformateur de données comme superjson, vous devez le passer à la configuration du client. Sans cela, les Dates, Maps, Sets et autres types non-JSON peuvent être incorrects silencieusement.
Générez d'abord votre code client via l'API programmatique de Hey API. Ainsi vous pouvez utiliser createTRPCHeyApiTypeResolvers pour garantir que vos types émis sont corrects :
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' },},],});
Au runtime, configurez le client généré avec votre transformateur. Vous pourrez alors passer des types natifs directement et les récupérer désérialisés :
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') },});
Utiliser un autre générateur ou langage
La spécification OpenAPI générée fonctionne avec tout générateur de client compatible OpenAPI qui peut :
-
Émettre des types précis pour des classes comme Date
-
Prendre en charge la personnalisation des paramètres de recherche et de la sérialisation des corps de requête/réponse
Pour une intégration correcte avec le protocole tRPC, vous devez configurer votre client généré pour effectuer deux actions :
-
Transformateurs — Si votre API tRPC utilise un transformateur, le client doit sérialiser les entrées et désérialiser les sorties en utilisant le même format
-
Entrées de requête — Les requêtes GET encodent les entrées sous la forme
?input=<JSON>, et non comme des paramètres de requête individuels
Consultez le code source de configuration Hey API pour une implémentation de référence complète.
Transformateurs
Les transformateurs de données tRPC vous permettent d'envoyer des types complexes comme Date, Map, Set et BigInt via le réseau. Lorsque vous utilisez le client OpenAPI, le même transformateur doit être configuré côté serveur et client pour que les entrées soient sérialisées et les sorties désérialisées correctement.
Tout transformateur implémentant l'interface DataTransformer de tRPC (serialize / deserialize) fonctionne avec configureTRPCHeyApiClient. Voici quelques options testées.
SuperJSON
Le transformateur le plus populaire pour les configurations TypeScript-to-TypeScript. Gère Date, Map, Set, BigInt, RegExp et plus encore.
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,});
Consultez le test superjson pour un exemple complet de bout en bout.
MongoDB Extended JSON v2
EJSON est un bon choix lorsque vous avez besoin d'une prise en charge multilingue. Le package npm bson fournit EJSON.serialize / EJSON.deserialize qui correspondent directement à un DataTransformer 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,});
Consultez le test MongoDB EJSON pour un exemple complet de bout en bout.
Amazon Ion
Amazon Ion est un format de données richement typé avec une large prise en charge linguistique. Il ne prend pas directement en charge l'interface TRPCDataTransformer et nécessite un peu de code passe-partout pour fonctionner avec tRPC en JS/TS, mais peut être un bon choix pour votre propre système.
Disponible en : C, C#, D, Go, Java, JavaScript, PHP, Python, Rust
bashpnpm add ion-js
bashpnpm add ion-js
Consultez le test Amazon Ion pour l'implémentation du transformateur, le code passe-partout et un exemple complet de bout en bout.
Création d'un transformateur personnalisé
Tout objet avec des méthodes serialize et deserialize fonctionne :
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 */},};
Transmettez-le à la fois à initTRPC.create({ transformer }) côté serveur et à configureTRPCHeyApiClient(client, { transformer }) côté client. Consultez la documentation sur les transformateurs de données pour plus de détails.
Exemple complet
Pour un projet exécutable complet qui rassemble toutes ces étapes, consultez l'exemple openapi-codegen.