Skip to content

OpenAPI Specification

oRPC uses the OpenAPI Specification to define APIs. It is fully compatible with OpenAPILink and OpenAPIHandler.

Installation

sh
npm install @orpc/openapi@latest
sh
yarn add @orpc/openapi@latest
sh
pnpm add @orpc/openapi@latest
sh
bun add @orpc/openapi@latest
sh
deno install npm:@orpc/openapi@latest

Generating Specifications

oRPC supports OpenAPI 3.1.1 and integrates seamlessly with popular schema libraries like Zod, and Valibot. You can generate specifications from either a Router or a Contract:

INFO

Interested in support for additional schema libraries? Let us know!

ts
import { 
OpenAPIGenerator
} from '@orpc/openapi'
import {
ZodToJsonSchemaConverter
} from '@orpc/zod'
import {
experimental_ValibotToJsonSchemaConverter
as
ValibotToJsonSchemaConverter
} from '@orpc/valibot'
const
openAPIGenerator
= new
OpenAPIGenerator
({
schemaConverters
: [
new
ZodToJsonSchemaConverter
(), // <-- if you use Zod
new
ValibotToJsonSchemaConverter
(), // <-- if you use Valibot
], }) const
specFromContract
= await
openAPIGenerator
.
generate
(
contract
, {
info
: {
title
: 'My App',
version
: '0.0.0',
}, }) const
specFromRouter
= await
openAPIGenerator
.
generate
(
router
, {
info
: {
title
: 'My App',
version
: '0.0.0',
}, })

WARNING

Features prefixed with experimental_ are unstable and may lack some functionality.

Operation Metadata

You can enrich your API documentation by specifying operation metadata using the .route or .tag:

ts
const ping = os
  .route({
    summary: 'the summary',
    description: 'the description',
    deprecated: false,
    tags: ['tag'],
    successDescription: 'the success description',
  })
  .handler(() => {})

// or append tag for entire router

const router = os.tag('planets').router({
  // ...
})

File Schema

In the File Upload/Download guide, z.instanceof is used to describe file/blob schemas. However, this method prevents oRPC from recognizing file/blob schema. Instead, use the enhanced file schema approach:

ts
import { 
z
} from 'zod'
import {
oz
} from '@orpc/zod'
const
InputSchema
=
z
.
object
({
file
:
oz
.
file
(),
image
:
oz
.
file
().
type
('image/*'),
blob
:
oz
.
blob
()
})

Customizing Operation Objects

You can also extend the operation object using the .spec helper for an error or middleware:

ts
import { oo } from '@orpc/openapi'

const base = os.errors({
  UNAUTHORIZED: oo.spec({
    data: z.any(),
  }, {
    security: [{ 'api-key': [] }],
  })
})

// OR in middleware

const requireAuth = oo.spec(
  os.middleware(async ({ next, errors }) => {
    throw new ORPCError('UNAUTHORIZED')
    return next()
  }),
  {
    security: [{ 'api-key': [] }]
  }
)

Any procedure that includes the use above errors or middleware will automatically have the defined security property applied

INFO

The .spec helper accepts a callback as its second argument, allowing you to override the entire operation object.

JSON Schema Customization

If Zod alone does not cover your JSON Schema requirements, you can extend or override the generated schema:

ts
import { 
z
} from 'zod'
import {
oz
} from '@orpc/zod'
const
InputSchema
=
oz
.
openapi
(
z
.
object
({
name
:
z
.
string
(),
}), {
examples
: [
{
name
: 'Earth' },
{
name
: 'Mars' },
], // additional options... } )

Released under the MIT License.