Skip to content
You are reading the v2 docs, currently in beta.V1 docs
oRPC
Esc
↑↓navigate↵open⌘Jpreview
On this page

Fetch API Adapter

Use oRPC with the Fetch API on both servers and clients, in runtimes such as Bun and Deno, and configure how event streams are sent to the client.

Server Usage

import { RPCHandler } from '@orpc/server/fetch'
import { CORSHandlerPlugin } from '@orpc/server/plugins'
import { onError } from '@orpc/server'

const handler = new RPCHandler(router, {
  plugins: [
    new CORSHandlerPlugin()
  ],
  interceptors: [
    onError((error) => {
      console.error(error)
    }),
  ],
})

export async function fetch(request: Request): Promise<Response> {
  const { matched, response } = await handler.handle(request, {
    prefix: '/rpc',
    context: {} // Provide initial context if needed, can be an async function
  })

  if (matched) {
    return response
  }

  return new Response('Not found', { status: 404 })
}
import { OpenAPIHandler } from '@orpc/openapi/fetch'
import { CORSHandlerPlugin } from '@orpc/server/plugins'
import { onError } from '@orpc/server'

const handler = new OpenAPIHandler(router, {
  plugins: [
    new CORSHandlerPlugin()
  ],
  interceptors: [
    onError((error) => {
      console.error(error)
    }),
  ],
})

export async function fetch(request: Request): Promise<Response> {
  const { matched, response } = await handler.handle(request, {
    prefix: '/api',
    context: {} // Provide initial context if needed, can be an async function
  })

  if (matched) {
    return response
  }

  return new Response('Not found', { status: 404 })
}

Client Usage

import { RPCLink } from '@orpc/client/fetch'
import { onError } from '@orpc/client'

const link = new RPCLink({
  origin: 'https://api.example.com', // accepts async function, defaults to current origin
  url: '/rpc', // accepts async function
  headers: { authorization: 'bearer token' }, // accept async function
  interceptors: [
    onError((error) => {
      console.error(error)
    }),
  ],
  fetch: (request, init) => { // <- override fetch if needed
    return globalThis.fetch(request, {
      ...init,
      credentials: 'include', // Include cookies on cross-origin requests
    })
  },
})
import { OpenAPILink } from '@orpc/openapi/fetch'
import { onError } from '@orpc/client'

const link = new OpenAPILink(contract, {
  origin: 'https://api.example.com', // accepts async function, defaults to current origin
  url: '/rpc', // accepts async function
  headers: { authorization: 'bearer token' }, // accept async function
  interceptors: [
    onError((error) => {
      console.error(error)
    }),
  ],
  fetch: (request, init) => { // <- override fetch if needed
    return globalThis.fetch(request, {
      ...init,
      credentials: 'include', // Include cookies on cross-origin requests
    })
  },
})

Event Stream Options

You can configure how an AsyncIteratorObject is streamed to the client using the toFetchResponse.eventStream options when creating the handler.

const handler = new OpenAPIHandler(router, {
  toFetchResponse: {
    eventStream: {
      initialComment: {
        /**
         * If true, an initial comment is sent immediately upon stream start to flush headers.
         * This allows the receiving side to establish the connection without waiting for the first event.
         *
         * @default true
         */
        enabled: true,
        /**
         * The content of the initial comment sent upon stream start. Must not include newline characters.
         *
         * @default ''
         */
        comment: '',
      },
      keepAlive: {
        /**
         * If true, a ping comment is sent periodically to keep the connection alive.
         *
         * @default true
         */
        enabled: true,
        /**
         * Interval (in milliseconds) between ping comments sent after the last event.
         *
         * @default 15000
         */
        interval: 15000,
        /**
         * The content of the ping comment. Must not include newline characters.
         *
         * @default ''
         */
        comment: '',
      },
    },
  },
})

Last updated on

Was this page helpful?