Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork183
trpc/trpc-openapi
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Note
Repo is archived due to not having maintainers - feel free to contact us if you want to take over maintenance.
Otherwise, we might reintroduce trpc-openapi to the world as a paid package.
For now, look athttps://www.npmjs.com/package/trpc-to-openapi for an alternative
trpc-openapi
is maintained by ProsePilot - simple, fast and free onlinewriting tools.
- Easy REST endpoints for your tRPC procedures.
- Perfect for incremental adoption.
- OpenAPI version 3.0.3.
1. Installtrpc-openapi
.
# npmnpm install trpc-openapi# yarnyarn add trpc-openapi
2. AddOpenApiMeta
to your tRPC instance.
import{initTRPC}from'@trpc/server';import{OpenApiMeta}from'trpc-openapi';constt=initTRPC.meta<OpenApiMeta>().create();/* 👈 */
3. Enableopenapi
support for a procedure.
exportconstappRouter=t.router({sayHello:t.procedure.meta({/* 👉 */openapi:{method:'GET',path:'/say-hello'}}).input(z.object({name:z.string()})).output(z.object({greeting:z.string()})).query(({ input})=>{return{greeting:`Hello${input.name}!`};});});
4. Generate an OpenAPI document.
import{generateOpenApiDocument}from'trpc-openapi';import{appRouter}from'../appRouter';/* 👇 */exportconstopenApiDocument=generateOpenApiDocument(appRouter,{title:'tRPC OpenAPI',version:'1.0.0',baseUrl:'http://localhost:3000',});
5. Add antrpc-openapi
handler to your app.
We currently support adapters forExpress
,Next.js
,Serverless
,Fastify
,Nuxt
&Node:HTTP
.
Fetch
,Cloudflare Workers
& more soon™, PRs are welcomed 🙌.
importhttpfrom'http';import{createOpenApiHttpHandler}from'trpc-openapi';import{appRouter}from'../appRouter';constserver=http.createServer(createOpenApiHttpHandler({router:appRouter}));/* 👈 */server.listen(3000);
6. Profit 🤑
// client.tsconstres=awaitfetch('http://localhost:3000/say-hello?name=James',{method:'GET'});constbody=awaitres.json();/* { greeting: 'Hello James!' } */
Peer dependencies:
tRPC
Server v10 (@trpc/server
) must be installed.Zod
v3 (zod@^3.14.4
) must be installed (recommended^3.20.0
).
For a procedure to support OpenAPI the followingmust be true:
- Both
input
andoutput
parsers are present AND useZod
validation. - Query
input
parsers extendObject<{ [string]: String | Number | BigInt | Date }>
orVoid
. - Mutation
input
parsers extendObject<{ [string]: AnyType }>
orVoid
. meta.openapi.method
isGET
,POST
,PATCH
,PUT
orDELETE
.meta.openapi.path
is a string starting with/
.meta.openapi.path
parameters exist ininput
parser asString | Number | BigInt | Date
Please note:
- Data
transformers
(such assuperjson
) are ignored. - Trailing slashes are ignored.
- Routing is case-insensitive.
Procedures with aGET
/DELETE
method will accept inputs via URLquery parameters
. Procedures with aPOST
/PATCH
/PUT
method will accept inputs via therequest body
with aapplication/json
orapplication/x-www-form-urlencoded
content type.
A procedure can accept a set of inputs via URL path parameters. You can add a path parameter to any OpenAPI procedure by using curly brackets around an input name as a path segment in themeta.openapi.path
field.
Query & path parameter inputs are always accepted as astring
. This library will attempt tocoerce your input values to the following primitive types out of the box:number
,boolean
,bigint
anddate
. If you wish to support others such asobject
,array
etc. please usez.preprocess()
.
// RouterexportconstappRouter=t.router({sayHello:t.procedure.meta({openapi:{method:'GET',path:'/say-hello/{name}'/* 👈 */}}).input(z.object({name:z.string()/* 👈 */,greeting:z.string()})).output(z.object({greeting:z.string()})).query(({ input})=>{return{greeting:`${input.greeting}${input.name}!`};});});// Clientconstres=awaitfetch('http://localhost:3000/say-hello/James?greeting=Hello'/* 👈 */,{method:'GET',});constbody=awaitres.json();/* { greeting: 'Hello James!' } */
// RouterexportconstappRouter=t.router({sayHello:t.procedure.meta({openapi:{method:'POST',path:'/say-hello/{name}'/* 👈 */}}).input(z.object({name:z.string()/* 👈 */,greeting:z.string()})).output(z.object({greeting:z.string()})).mutation(({ input})=>{return{greeting:`${input.greeting}${input.name}!`};});});// Clientconstres=awaitfetch('http://localhost:3000/say-hello/James'/* 👈 */,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({greeting:'Hello'}),});constbody=awaitres.json();/* { greeting: 'Hello James!' } */
Any custom headers can be specified in themeta.openapi.headers
array, these headers will not be validated on request. Please consider usingAuthorization for first-class OpenAPI auth/security support.
Status codes will be200
by default for any successful requests. In the case of an error, the status code will be derived from the thrownTRPCError
or fallback to500
.
You can modify the status code or headers for any response using theresponseMeta
function.
Please seeerror status codes here.
To create protected endpoints, addprotect: true
to themeta.openapi
object of each tRPC procedure. By default, you can then authenticate each request with thecreateContext
function using theAuthorization
header with theBearer
scheme. If you wish to authenticate requests using a different/additional methods (such as custom headers, or cookies) this can be overwritten by specifyingsecuritySchemes
object.
Explore acomplete example here.
import{TRPCError,initTRPC}from'@trpc/server';import{OpenApiMeta}from'trpc-openapi';typeUser={id:string;name:string};constusers:User[]=[{id:'usr_123',name:'James',},];exporttypeContext={user:User|null};exportconstcreateContext=async({ req, res}):Promise<Context>=>{letuser:User|null=null;if(req.headers.authorization){constuserId=req.headers.authorization.split(' ')[1];user=users.find((_user)=>_user.id===userId);}return{ user};};constt=initTRPC.context<Context>().meta<OpenApiMeta>().create();exportconstappRouter=t.router({sayHello:t.procedure.meta({openapi:{method:'GET',path:'/say-hello',protect:true/* 👈 */}}).input(z.void())// no input expected.output(z.object({greeting:z.string()})).query(({ input, ctx})=>{if(!ctx.user){thrownewTRPCError({message:'User not found',code:'UNAUTHORIZED'});}return{greeting:`Hello${ctx.user.name}!`};}),});
constres=awaitfetch('http://localhost:3000/say-hello',{method:'GET',headers:{Authorization:'Bearer usr_123'}/* 👈 */,});constbody=awaitres.json();/* { greeting: 'Hello James!' } */
For advanced use-cases, please find examples in ourcomplete test suite.
Please seefull example here.
import{createExpressMiddleware}from'@trpc/server/adapters/express';importexpressfrom'express';import{createOpenApiExpressMiddleware}from'trpc-openapi';import{appRouter}from'../appRouter';constapp=express();app.use('/api/trpc',createExpressMiddleware({router:appRouter}));app.use('/api',createOpenApiExpressMiddleware({router:appRouter}));/* 👈 */app.listen(3000);
Please seefull example here.
// pages/api/[...trpc].tsimport{createOpenApiNextHandler}from'trpc-openapi';import{appRouter}from'../../server/appRouter';exportdefaultcreateOpenApiNextHandler({router:appRouter});
Please seefull example here.
import{createOpenApiAwsLambdaHandler}from'trpc-openapi';import{appRouter}from'./appRouter';exportconstopenApi=createOpenApiAwsLambdaHandler({router:appRouter});
Please seefull example here.
import{fastifyTRPCPlugin}from'@trpc/server/adapters/fastify';importFastifyfrom'fastify';import{fastifyTRPCOpenApiPlugin}from'trpc-openapi';import{appRouter}from'./router';constfastify=Fastify();asyncfunctionmain(){awaitfastify.register(fastifyTRPCPlugin,{router:appRouter});awaitfastify.register(fastifyTRPCOpenApiPlugin,{router:appRouter});/* 👈 */awaitfastify.listen({port:3000});}main();
Please seefull typings here.
Property | Type | Description | Required |
---|---|---|---|
title | string | The title of the API. | true |
description | string | A short description of the API. | false |
version | string | The version of the OpenAPI document. | true |
baseUrl | string | The base URL of the target server. | true |
docsUrl | string | A URL to any external documentation. | false |
tags | string[] | A list for ordering endpoint groups. | false |
securitySchemes | Record<string, SecuritySchemeObject> | Defaults toAuthorization header withBearer scheme | false |
Please seefull typings here.
Property | Type | Description | Required | Default |
---|---|---|---|---|
enabled | boolean | Exposes this procedure totrpc-openapi adapters and on the OpenAPI document. | false | true |
method | HttpMethod | HTTP method this endpoint is exposed on. Value can beGET ,POST ,PATCH ,PUT orDELETE . | true | undefined |
path | string | Pathname this endpoint is exposed on. Value must start with/ , specify path parameters using{} . | true | undefined |
protect | boolean | Requires this endpoint to use a security scheme. | false | false |
summary | string | A short summary of the endpoint included in the OpenAPI document. | false | undefined |
description | string | A verbose description of the endpoint included in the OpenAPI document. | false | undefined |
tags | string[] | A list of tags used for logical grouping of endpoints in the OpenAPI document. | false | undefined |
headers | ParameterObject[] | An array of custom headers to add for this endpoint in the OpenAPI document. | false | undefined |
contentTypes | ContentType[] | A set of content types specified as accepted in the OpenAPI document. | false | ['application/json'] |
deprecated | boolean | Whether or not to mark an endpoint as deprecated | false | false |
Please seefull typings here.
Property | Type | Description | Required |
---|---|---|---|
router | Router | Your application tRPC router. | true |
createContext | Function | Passes contextual (ctx ) data to procedure resolvers. | false |
responseMeta | Function | Returns any modifications to statusCode & headers. | false |
onError | Function | Called if error occurs inside handler. | false |
maxBodySize | number | Maximum request body size in bytes (default: 100kb). | false |
Still using tRPC v9? See our.interop()
example.
Distributed under the MIT License. See LICENSE for more information.
James Berry - Follow me on Twitter@jlalmes 💚
About
OpenAPI support for tRPC 🧩
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.