Skip to content

Commit a98d50e

Browse files
committed
settled on unofficia trpc package instead of official alpha.
1 parent 136035c commit a98d50e

1 file changed

Lines changed: 62 additions & 53 deletions

File tree

openapi/frameworks/trpc.mdx

Lines changed: 62 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,35 @@ import { Callout } from "@/mdx/components";
88
# How to generate OpenAPI with tRPC
99

1010
This tutorial explores how to add REST endpoints to [tRPC](https://trpc.io/)
11-
procedures, then generate an OpenAPI document for that API, and finally uses
12-
this document to create an SDK using Speakeasy.
11+
procedures, then turn all those convenient types into generated OpenAPI which
12+
can be used for all sorts of handy things like creating an SDK with Speakeasy.
1313

1414
The guide covers:
1515

16-
- Adding REST-like HTTP endpoints to a tRPC project and making OpenAPI v3.1 for
17-
it, all using [`trpc-to-openapi`](](https://github.com/mcampa/trpc-to-openapi)).
16+
- Adding REST-like HTTP endpoints to a tRPC project and making OpenAPI v3.1
17+
using [`trpc-to-openapi`](](https://github.com/mcampa/trpc-to-openapi)).
1818
- Improving the generated OpenAPI for better use across the API lifecycle and
1919
specifically SDK generation.
2020
- Using the Speakeasy CLI to create an SDK based on the generated OpenAPI.
2121

22-
<Callout title="Sample code" type="info">
23-
Follow along with this guide using the sample code in the [Speakeasy examples
24-
repository](https://github.com/speakeasy-api/examples/), with this code living
25-
under <code>frameworks-trpc</code>. This sample code is based on the common OpenAPI
26-
example: the [Train Travel API](https://github.com/bump-sh-examples/train-travel-api).
27-
</Callout>
28-
2922
## Introduction
3023

31-
tRPC does not natively export OpenAPI documents, but the
32-
[`trpc-to-openapi`](https://github.com/mcampa/trpc-to-openapi) package adds this
33-
functionality. The tutorial starts by adding `trpc-to-openapi` to a project, and
34-
then adds a script to generate an OpenAPI schema and save it as a file.
24+
tRPC does not natively export OpenAPI documents, but seeing as both tRPC and
25+
OpenAPI are focused on declaring types and operations it's not a huge task to
26+
turn one into the other.
3527

36-
The quality of the OpenAPI description will ultimately determine the quality of
37-
created SDKs and documentation, so this guide covers ways to improve the
38-
generated OpenAPI document.
28+
The [`trpc-to-openapi`](https://github.com/mcampa/trpc-to-openapi) package does
29+
exactly this, adding full OpenAPI support to tRPC. Hang on though, isn't OpenAPI
30+
meant to describe REST/RESTish APIs, not tRPC specifically? Well absolutely, the
31+
`trpc-to-openapi` creates a REST bridge for the tRPC procedures, making them
32+
accessible to the wider public allowing for more potential integrations on the
33+
same API, then describe it nicely to allow for documentation making that
34+
integration even easier.
3935

40-
With the new and improved OpenAPI document in hand, the next step is to create
41-
SDKs using Speakeasy.
36+
The quality of the generated OpenAPI will ultimately determine the quality of
37+
created SDKs and documentation, so this guide covers ways to improve the that
38+
OpenAPI by leveraging all sorts of handy features in tRPC, OpenAPI, and the
39+
integrations between the two.
4240

4341
Finally, this process is added to a CI/CD pipeline so that Speakeasy
4442
automatically creates fresh SDKs whenever the tRPC API changes in the future.
@@ -47,11 +45,18 @@ automatically creates fresh SDKs whenever the tRPC API changes in the future.
4745

4846
To follow along with this tutorial, the following are needed:
4947

50-
- An existing tRPC app, or the example application can be cloned.
5148
- Some familiarity with tRPC.
5249
- [Node.js](https://nodejs.org/en/download) (Node 26.3.0 was used here).
5350
- The [Speakeasy CLI](/docs/speakeasy-cli/). The CLI creates the SDK once the
5451
OpenAPI document has been generated.
52+
- An existing tRPC app, or the [example application](https://github.com/speakeasy-api/examples) can be cloned.
53+
54+
<Callout title="Sample code" type="info">
55+
Follow along with this guide using the sample code in the [Speakeasy examples
56+
repository](https://github.com/speakeasy-api/examples/), with this code living
57+
under <code>frameworks-trpc</code>. This sample code is based on a common OpenAPI
58+
example: the [Train Travel API](https://github.com/bump-sh-examples/train-travel-api).
59+
</Callout>
5560

5661
The specific versions will change over time, but these are the versions used in
5762
this guide and the accompanying sample code:
@@ -84,15 +89,15 @@ make a huge difference as lots of tools work just fine with either version.
8489

8590
## Adding easy REST-like endpoints to tRPC procedures
8691

87-
The `trpc-to-openapi` library has two main features: adding REST-like endpoints
92+
The `trpc-to-openapi` library has two main features: adding REST/RESTish endpoints
8893
to tRPC procedures, and generating an OpenAPI document for these endpoints.
8994

90-
Why would you want to add REST-like endpoints to tRPC procedures? For the same
91-
reason gRPC has the gRPC Gateway to turn services into REST-like endpoints: at
92-
first some teams pick something expecting it only to be used by them, but later
93-
they want to expose it to other teams or external developers. Adding REST-like
94-
endpoints to tRPC procedures allows APIs to be opened up to a wide variety of
95-
users who don't all want to learn tRPC.
95+
Why would you want to add REST endpoints to tRPC procedures? For the same
96+
reason gRPC has the [gRPC Gateway](/openapi/frameworks/grpc-gateway) to turn
97+
services into REST endpoints: at first some teams pick something expecting
98+
it only to be used by them, but later they want to expose it to other teams or
99+
external developers. Adding REST endpoints to tRPC procedures allows APIs
100+
to be opened up to a wide variety of users who don't all want to learn tRPC.
96101

97102
First step, install `trpc-to-openapi`:
98103

@@ -199,10 +204,10 @@ directly, and getting it ready for OpenAPI to pick that up and add more context.
199204
## Configure OpenAPI from source code
200205

201206
With this handy new REST-like API setup with minimal HTTP mapping, we can now
202-
generate an OpenAPI document, and export it to something like `openapi.json` so
203-
it can be used by an entire [ecosystem of API tooling](https://openapi.tools/)
204-
for everything from mock servers and contract testing to API gateways and SDK
205-
generation.
207+
generate an OpenAPI document and export it to something like `openapi-spec.json`.
208+
Once this files exists, it can be used by a [massive ecosystem of API
209+
tooling](https://openapi.tools/) for everything from mock servers and contract
210+
testing to API gateways and SDK generation.
206211

207212
OpenAPI requires a little bit more than just a list of HTTP methods and paths,
208213
so the next step is to add some basic information about the API to the OpenAPI
@@ -244,7 +249,7 @@ like:
244249
}
245250
```
246251

247-
Staring into this void of JSON is not very useful, so let's make another handy
252+
Staring directly into the void of JSON is not very useful, so let's make another handy
248253
script to save it to a file so other tools can work with it.
249254

250255
```json filename="package.json"
@@ -261,7 +266,7 @@ From now on, an OpenAPI document can be generated by running `npm run generate-o
261266

262267
The team over at [Scalar](https://scalar.com/) have built a fantastic CLI and
263268
documentation tool which can serve an OpenAPI document as a web app, using the
264-
Stripe-like "three column" API documentation format.
269+
popular Stripe-like "three column" API documentation format.
265270

266271
```json
267272
{
@@ -369,11 +374,15 @@ Run `npm run generate-openapi` and see how this information is added to the Open
369374

370375
## Improving the OpenAPI paths
371376

372-
The OpenAPI document can be improved by adding fields to the procedure's input and output schemas, and by adding examples, documentation, and metadata.
377+
With the generic information covered in the `intro` section, it's time to focus
378+
on documenting the procedures (or in OpenAPI: operations), which is achieved by
379+
adding more fields to the procedure's input and output schemas. The fields being
380+
added cover examples, documentation, and metadata.
373381

374382
### Expanding the procedure's input and output schemas
375383

376-
Let's create a `Station` model and add a few field types to see how these are represented in the OpenAPI document.
384+
Let's create a `Station` model and add a few field types to see how these are
385+
represented in the OpenAPI document.
377386

378387
Create a new file called `shared/models.ts` and specify a `Station` model using Zod:
379388

@@ -409,7 +418,8 @@ export const StationSchema = z.object({
409418
export type Station = z.infer<typeof StationSchema>;
410419
```
411420

412-
Back in `server/router.ts`, import these models and update the procedure's input and output schemas. In the example app, a mock database is also added.
421+
Back in `server/router.ts`, import these models and update the procedure's input
422+
and output schemas. In the example app, a mock database is also added.
413423

414424
```typescript filename="server/router.ts"
415425
import { initTRPC } from "@trpc/server";
@@ -447,7 +457,8 @@ export const appRouter = t.router({
447457
});
448458
```
449459

450-
After the OpenAPI document is regenerated, the `Station` model is included in the document with all of its fields:
460+
After the OpenAPI document is regenerated, the `Station` model is included in
461+
the document with all of its fields:
451462

452463
```json filename="openapi-spec.json"
453464
{
@@ -556,7 +567,7 @@ instead of being duplicated inline.
556567

557568
Under the hood, `trpc-to-openapi` uses the
558569
[`zod-openapi`](https://github.com/samchungy/zod-openapi) package to convert Zod
559-
schemas into OpenAPI schemas.
570+
schemas into OpenAPI documents.
560571

561572
### Adding a summary, description, examples, and tags to a procedure
562573

@@ -806,10 +817,6 @@ been added to the document.
806817

807818
## Why Speakeasy and tRPC?
808819

809-
tRPC's focus on type safety and developer experience sets it apart from other
810-
TypeScript API frameworks. By using TypeScript's type system along with a schema
811-
library like Zod, tRPC allows server and client code to share types.
812-
813820
One of tRPC's stated goals is to cut down on the need for codegen, but there is
814821
still a place for code generation in the tRPC ecosystem. While tRPC's [default
815822
client](https://trpc.io/docs/client/vanilla/setup) is useful for writing
@@ -818,14 +825,13 @@ internal clients in a monorepo where a client can import the server's
818825
by internal and external developers. Nor does tRPC's type-safety extend to SDKs
819826
in languages other than TypeScript.
820827

821-
Speakeasy can help create type-safe, production-ready SDKs for a tRPC API in
822-
various languages so that the API can be built with confidence that users will
823-
have a great developer experience.
828+
Speakeasy can help create type-safe, production-ready SDKs for a tRPC-base HTTP API in
829+
various languages, ensuring the released APIs will give users a great developer experience.
824830

825-
## How to create an SDK based on the OpenAPI spec
831+
## Create an SDK based on OpenAPI
826832

827-
After following the steps above, an OpenAPI spec is ready to use as the basis
828-
for a new SDK. Next, Speakeasy is used to create an SDK.
833+
After following the steps above, the OpenAPI document is ready to use as the basis
834+
for a new SDK.
829835

830836
In the root directory of the project, run the following:
831837

@@ -853,7 +859,10 @@ Generation Action and Workflows](/docs/workflow-reference) documentation.
853859

854860
## Alternative OpenAPI support in tRPC
855861

856-
The tRPC docs now include an OpenAPI page at
857-
[https://trpc.io/docs/openapi](https://trpc.io/docs/openapi). This guide does
858-
not use that approach yet because it is currently in alpha, so the examples here
859-
use `trpc-to-openapi` for a more established workflow.
862+
tRPC also has an official OpenAPI package, documented at
863+
[https://trpc.io/docs/openapi](https://trpc.io/docs/openapi) and implemented via
864+
`@trpc/openapi`. This is a valid option for teams that want to stay close to the
865+
official tRPC ecosystem, but it is still in alpha and the package API may still
866+
change as it matures. For that reason, the examples in this guide use
867+
`trpc-to-openapi`, which is a more established workflow today while still
868+
producing OpenAPI that works well with Speakeasy.

0 commit comments

Comments
 (0)