Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions apps/content/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -144,25 +144,26 @@ In oRPC middleware is very useful and fully typed you can find more info [here](
This example uses [@whatwg-node/server](https://www.npmjs.com/package/@whatwg-node/server) to create a Node server with [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).

```ts twoslash
import { createFetchHandler } from '@orpc/server/fetch'
import { handleFetchRequest, createORPCHandler } from '@orpc/server/fetch'
import { createOpenAPIServerlessHandler } from '@orpc/openapi/fetch'
import { createServer } from 'node:http'
import { createServerAdapter } from '@whatwg-node/server'
import { router } from 'examples/server'

const handler = createFetchHandler({
router,
serverless: false, // set true will improve cold start times
})

const server = createServer(
createServerAdapter((request: Request) => {
const url = new URL(request.url)

if (url.pathname.startsWith('/api')) {
return handler({
return handleFetchRequest({
router,
request,
prefix: '/api',
context: {},
handlers: [
createORPCHandler(),
createOpenAPIServerlessHandler(),
],
})
}

Expand Down
24 changes: 13 additions & 11 deletions apps/content/content/docs/server/context.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ If your procedure only depends on `Middleware Context`, you can

```ts twoslash
import { os, ORPCError } from '@orpc/server'
import { createFetchHandler } from '@orpc/server/fetch'
import { headers } from 'next/headers'

const base = os.use(async (input, context, meta) => {
Expand Down Expand Up @@ -83,14 +82,18 @@ export const router = base.router({
// You can call this procedure directly without manually providing context
const output = await router.getting()

const handler = createFetchHandler({
router,
})
import { handleFetchRequest, createORPCHandler } from '@orpc/server/fetch'
import { createOpenAPIServerlessHandler, createOpenAPIServerHandler } from '@orpc/openapi/fetch'

export function fetch(request: Request) {
// No need to pass context; middleware handles it
return handler({
return handleFetchRequest({
router,
request,
handlers: [
createORPCHandler(),
createOpenAPIServerlessHandler()
],
})
}
```
Expand All @@ -103,7 +106,8 @@ rather than relying on global mechanisms like `headers` or `cookies` in Next.js.

```ts twoslash
import { os, ORPCError, createProcedureCaller } from '@orpc/server'
import { createFetchHandler } from '@orpc/server/fetch'
import { handleFetchRequest, createORPCHandler } from '@orpc/server/fetch'
import { createOpenAPIServerlessHandler, createOpenAPIServerHandler } from '@orpc/openapi/fetch'

type ORPCContext = { user?: { id: string }, db: 'fake-db' }

Expand All @@ -129,18 +133,16 @@ export const router = base.router({
}),
})

const handler = createFetchHandler({
router,
})

export function fetch(request: Request) {
// Initialize context explicitly for each request
const db = 'fake-db' as const
const user = request.headers.get('Authorization') ? { id: 'example' } : undefined

return handler({
return handleFetchRequest({
router,
request,
context: { db, user },
handlers: [createORPCHandler(), createOpenAPIServerlessHandler()],
})
}

Expand Down
101 changes: 53 additions & 48 deletions apps/content/content/docs/server/integrations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@ Whether you're targeting serverless, edge environments, or traditional backends,
## Quick Example

```ts twoslash
import { createFetchHandler } from '@orpc/server/fetch'
import { handleFetchRequest, createORPCHandler } from '@orpc/server/fetch'
import { createOpenAPIServerlessHandler, createOpenAPIServerHandler } from '@orpc/openapi/fetch'
import { router } from 'examples/server'

const handler = createFetchHandler({
router,
serverless: false, // Set true for faster cold starts
})

export function fetch(request: Request) {
return handler({
return handleFetchRequest({
router,
request,
context: {},
// prefix: '/api', // Optionally define a route prefix
handlers: [
createORPCHandler(),
createOpenAPIServerlessHandler(),
],
})
}
```
Expand All @@ -36,22 +37,23 @@ Node.js doesn't provide native support for creating server with [Fetch API](http
but you can easily use [@whatwg-node/server](https://npmjs.com/package/@whatwg-node/server) as an adapter.

```ts twoslash
import { createFetchHandler } from '@orpc/server/fetch'
import { handleFetchRequest, createORPCHandler } from '@orpc/server/fetch'
import { createOpenAPIServerlessHandler, createOpenAPIServerHandler } from '@orpc/openapi/fetch'
import { createServer } from 'node:http'
import { createServerAdapter } from '@whatwg-node/server'
import { router } from 'examples/server'

const handler = createFetchHandler({
router,
serverless: false,
})

const server = createServer(
createServerAdapter((request: Request) => {
return handler({
return handleFetchRequest({
router,
request,
context: {},
// prefix: '/api',
handlers: [
createORPCHandler(),
createOpenAPIServerlessHandler(),
],
})
})
)
Expand All @@ -64,23 +66,24 @@ server.listen(3000, () => {
## Express.js

```ts twoslash
import { createFetchHandler } from '@orpc/server/fetch'
import { handleFetchRequest, createORPCHandler } from '@orpc/server/fetch'
import { createOpenAPIServerlessHandler, createOpenAPIServerHandler } from '@orpc/openapi/fetch'
import { createServerAdapter } from '@whatwg-node/server'
import express from 'express'
import { router } from 'examples/server'

const handler = createFetchHandler({
router,
serverless: false,
})

const app = express()

app.all('/api/*', createServerAdapter((request: Request) => {
return handler({
return handleFetchRequest({
router,
request,
context: {},
prefix: '/api',
handlers: [
createORPCHandler(),
createOpenAPIServerHandler(),
],
})
}))

Expand All @@ -93,21 +96,22 @@ app.listen(3000, () => {

```ts twoslash
import { Hono } from 'hono'
import { createFetchHandler } from '@orpc/server/fetch'
import { handleFetchRequest, createORPCHandler } from '@orpc/server/fetch'
import { createOpenAPIServerlessHandler, createOpenAPIServerHandler } from '@orpc/openapi/fetch'
import { router } from 'examples/server'

const handler = createFetchHandler({
router,
serverless: false,
})

const app = new Hono()

app.get('/api/*', (c) => {
return handler({
return handleFetchRequest({
router,
request: c.req.raw,
prefix: '/api',
context: {},
handlers: [
createORPCHandler(),
createOpenAPIServerlessHandler(),
],
})
})

Expand All @@ -117,46 +121,47 @@ export default app
## Next.js

```ts title="app/api/[...orpc]/route.ts" twoslash
import { createFetchHandler } from '@orpc/server/fetch'
import { handleFetchRequest, createORPCHandler } from '@orpc/server/fetch'
import { createOpenAPIServerlessHandler, createOpenAPIServerHandler } from '@orpc/openapi/fetch'
import { router } from 'examples/server'

const handler = createFetchHandler({
router,
serverless: true,
})

const fetchRequestHandler = async (request: Request) => {
return handler({
export function GET(request: Request) {
return handleFetchRequest({
router,
request,
prefix: '/api',
context: {},
handlers: [
createORPCHandler(),
createOpenAPIServerlessHandler(),
],
})
}

export const GET = fetchRequestHandler
export const POST = fetchRequestHandler
export const PUT = fetchRequestHandler
export const DELETE = fetchRequestHandler
export const PATCH = fetchRequestHandler
export const POST = GET
export const PUT = GET
export const DELETE = GET
export const PATCH = GET
```

## Cloudflare Workers

```ts twoslash
import { createFetchHandler } from '@orpc/server/fetch'
import { handleFetchRequest, createORPCHandler } from '@orpc/server/fetch'
import { createOpenAPIServerlessHandler, createOpenAPIServerHandler } from '@orpc/openapi/fetch'
import { router } from 'examples/server'

const handler = createFetchHandler({
router,
serverless: true,
})

export default {
async fetch(request: Request) {
return handler({
return handleFetchRequest({
router,
request,
prefix: '/',
context: {},
handlers: [
createORPCHandler(),
createOpenAPIServerlessHandler(),
],
})
},
}
Expand Down
26 changes: 12 additions & 14 deletions apps/content/examples/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,6 @@ import { z } from 'zod'

import { ORPCError, os } from '@orpc/server'

// Expose apis to the internet with fetch handler

import { createFetchHandler } from '@orpc/server/fetch'

// Modern runtime that support fetch api like deno, bun, cloudflare workers, even node can used

import { createServer } from 'node:http'
import { createServerAdapter } from '@whatwg-node/server'

// Define your contract first
// This contract can replace server router in most-case

Expand Down Expand Up @@ -123,20 +114,27 @@ export const router = pub.router({
},
})

const handler = createFetchHandler({
router,
serverless: false, // set true will improve cold start times
})
// Expose apis to the internet with fetch handler
import { createOpenAPIServerlessHandler } from '@orpc/openapi/fetch'
import { createORPCHandler, handleFetchRequest } from '@orpc/server/fetch'
// Modern runtime that support fetch api like deno, bun, cloudflare workers, even node can used
import { createServer } from 'node:http'
import { createServerAdapter } from '@whatwg-node/server'

const server = createServer(
createServerAdapter((request: Request) => {
const url = new URL(request.url)

if (url.pathname.startsWith('/api')) {
return handler({
return handleFetchRequest({
router,
request,
prefix: '/api',
context: {},
handlers: [
createORPCHandler(),
createOpenAPIServerlessHandler(),
],
})
}

Expand Down
26 changes: 12 additions & 14 deletions apps/content/examples/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@ import { ORPCError, os } from '@orpc/server'
import { oz } from '@orpc/zod'
import { z } from 'zod'

// Expose apis to the internet with fetch handler

import { createFetchHandler } from '@orpc/server/fetch'

// Modern runtime that support fetch api like deno, bun, cloudflare workers, even node can used

import { createServer } from 'node:http'
import { createServerAdapter } from '@whatwg-node/server'

export type Context = { user?: { id: string } }

// global pub, authed completely optional
Expand Down Expand Up @@ -97,20 +88,27 @@ export const router = pub.router({
export type Inputs = InferRouterInputs<typeof router>
export type Outputs = InferRouterOutputs<typeof router>

const handler = createFetchHandler({
router,
serverless: false, // set true will improve cold start times
})
// Expose apis to the internet with fetch handler
import { createOpenAPIServerlessHandler } from '@orpc/openapi/fetch'
import { createORPCHandler, handleFetchRequest } from '@orpc/server/fetch'
// Modern runtime that support fetch api like deno, bun, cloudflare workers, even node can used
import { createServer } from 'node:http'
import { createServerAdapter } from '@whatwg-node/server'

const server = createServer(
createServerAdapter((request: Request) => {
const url = new URL(request.url)

if (url.pathname.startsWith('/api')) {
return handler({
return handleFetchRequest({
router,
request,
prefix: '/api',
context: {},
handlers: [
createORPCHandler(),
createOpenAPIServerlessHandler(),
],
})
}

Expand Down
5 changes: 5 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ export default antfu({
'unused-imports/no-unused-vars': 'off',
'antfu/no-top-level-await': 'off',
},
}, {
files: ['apps/content/examples/**'],
rules: {
'import/first': 'off',
},
}, {
files: ['playgrounds/**'],
rules: {
Expand Down
Loading