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, Valibot, and ArkType. 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' import {
experimental_ArkTypeToJsonSchemaConverter
as
ArkTypeToJsonSchemaConverter
} from '@orpc/arktype' const
openAPIGenerator
= new
OpenAPIGenerator
({
schemaConverters
: [
new
ZodToJsonSchemaConverter
(), // <-- if you use Zod
new
ValibotToJsonSchemaConverter
(), // <-- if you use Valibot
new
ArkTypeToJsonSchemaConverter
(), // <-- if you use ArkType
], }) 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({
  // ...
})

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.

@orpc/zod

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
()
})

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.