Aller au contenu principal
Version : 11.x

OpenAPI (alpha)

Traduction Bêta Non Officielle

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 →

attention

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

bash
pnpm add @trpc/openapi
bash
pnpm add @trpc/openapi
Agents IA

Si vous utilisez un agent de codage IA, installez les compétences tRPC pour une meilleure génération de code :

bash
npx @tanstack/intent@latest install
bash
npx @tanstack/intent@latest install
note

@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 champs description dans la spécification.

Générer la spécification

CLI

bash
pnpm exec trpc-openapi ./src/server/router.ts
bash
pnpm exec trpc-openapi ./src/server/router.ts
OptionDefaultDescription
-e, --export <name>AppRouterName of the exported router type
-o, --output <file>openapi.jsonOutput file path
--title <text>tRPC APIOpenAPI info.title
--version <ver>0.0.0OpenAPI info.version
bash
pnpm exec trpc-openapi ./src/server/router.ts -o api.json --title "My API" --version 1.0.0
bash
pnpm exec trpc-openapi ./src/server/router.ts -o api.json --title "My API" --version 1.0.0

Programmatique

scripts/generate-openapi.ts
ts
import { generateOpenAPIDocument } from '@trpc/openapi';
const doc = generateOpenAPIDocument('./src/server/router.ts', {
exportName: 'AppRouter',
title: 'My API',
version: '1.0.0',
});
scripts/generate-openapi.ts
ts
import { 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êtesGET /procedure.path

  • MutationsPOST /procedure.path

  • Abonnements ignorés (SSE à venir)

Hey API (TypeScript)

Documentation Hey API

bash
pnpm add @trpc/openapi @hey-api/openapi-ts
bash
pnpm 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.

bash
pnpm exec openapi-ts -i openapi.json -o ./generated
bash
pnpm exec openapi-ts -i openapi.json -o ./generated

Ensuite, une petite configuration est nécessaire au runtime :

src/usage.ts
ts
import { 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.ts
ts
import { 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.)

avertissement

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.ts
ts
import { 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.ts
ts
import { 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.ts
ts
import { 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.ts
ts
import { 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.

bash
pnpm add superjson
bash
pnpm add superjson
src/server.ts
ts
import { initTRPC } from '@trpc/server';
import superjson from 'superjson';
const t = initTRPC.create({ transformer: superjson });
src/server.ts
ts
import { initTRPC } from '@trpc/server';
import superjson from 'superjson';
const t = initTRPC.create({ transformer: superjson });
src/client.ts
ts
import { 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.ts
ts
import { 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

bash
pnpm add bson
bash
pnpm add bson
src/transformer.ts
ts
import { 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.ts
ts
import { 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.ts
ts
import { 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.ts
ts
import { 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

bash
pnpm add ion-js
bash
pnpm 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 :

ts
import type { TRPCDataTransformer } from '@trpc/server';
const myTransformer: TRPCDataTransformer = {
serialize: (value) => {
/* encode rich types */
},
deserialize: (value) => {
/* decode them back */
},
};
ts
import 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.