Skip to content

Commit 32a6de9

Browse files
authored
feat(client, server): batch request/response plugin (#329)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a Batch Request/Response capability that improves efficiency by enabling multiple requests to be processed together. - Updated the feature comparison to show full support for batch operations in the oRPC framework. - Added a new entry in the documentation sidebar for the Batch Request/Response Plugin. - **Documentation** - Added comprehensive documentation outlining how to configure and use the new batch processing feature, now accessible via an updated sidebar entry. - **Tests** - Expanded test coverage to ensure robust and reliable handling of batched requests across both client and server environments. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 25532a8 commit 32a6de9

File tree

21 files changed

+1811
-5
lines changed

21 files changed

+1811
-5
lines changed

apps/content/.vitepress/config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export default defineConfig({
109109
items: [
110110
{ text: 'CORS', link: '/docs/plugins/cors' },
111111
{ text: 'Response Headers', link: '/docs/plugins/response-headers' },
112+
{ text: 'Batch Request/Response', link: '/docs/plugins/batch-request-response' },
112113
{ text: 'Client Retry', link: '/docs/plugins/client-retry' },
113114
{ text: 'Body Limit', link: '/docs/plugins/body-limit' },
114115
],

apps/content/docs/comparison.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@ This comparison table helps you understand how oRPC differs from other popular T
3333
| Plugins-able (CORS, ...) ||| 🛑 |
3434
| Dedicated Zod Schemas || N/A | 🛑 |
3535
| Use Native Modules on each runtime ||| 🟡 |
36-
| Batch Request | 🛑 || 🛑 |
36+
| Batch Request | || 🛑 |
3737
| WebSockets | 🛑 || 🛑 |
3838
| Nest.js integration | 🛑 | 🟡 ||
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
---
2+
title: Batch Request/Response Plugin
3+
description: A plugin for oRPC to batch requests and responses.
4+
---
5+
6+
# Batch Request/Response Plugin
7+
8+
The **Batch Request/Response Plugin** allows you to combine multiple requests and responses into a single batch, reducing the overhead of sending each one separately.
9+
10+
:::info
11+
The **Batch Plugin** streams responses asynchronously so that no individual request blocks another, ensuring all responses are handled independently for faster, more efficient batching.
12+
:::
13+
14+
## Setup
15+
16+
This plugin requires configuration on both the server and client sides.
17+
18+
### Server
19+
20+
```ts twoslash
21+
import { RPCHandler } from '@orpc/server/fetch'
22+
import { router } from './shared/planet'
23+
// ---cut---
24+
import { BatchHandlerPlugin } from '@orpc/server/plugins'
25+
26+
const handler = new RPCHandler(router, {
27+
plugins: [new BatchHandlerPlugin()],
28+
})
29+
```
30+
31+
::: info
32+
The `handler` can be any supported oRPC handler, such as [RPCHandler](/docs/rpc-handler) or [OpenAPIHandler](/docs/openapi/openapi-handler). Note that this plugin uses its own protocol for batching requests and responses, which is different from the handler’s native protocol.
33+
:::
34+
35+
### Client
36+
37+
To use the `BatchLinkPlugin`, define at least one group. Requests within the same group will be batched together, and each group requires a `context` as described in [client context](/docs/client/rpc-link#using-client-context).
38+
39+
```ts twoslash
40+
import { RPCLink } from '@orpc/client/fetch'
41+
import { BatchLinkPlugin } from '@orpc/client/plugins'
42+
// ---cut---
43+
const link = new RPCLink({
44+
url: 'https://api.example.com/rpc',
45+
plugins: [
46+
new BatchLinkPlugin({
47+
groups: [
48+
{
49+
condition: options => true,
50+
context: {}
51+
}
52+
]
53+
}),
54+
],
55+
})
56+
```
57+
58+
## Limitations
59+
60+
The plugin does not support [AsyncIteratorObject](/docs/rpc-handler#supported-data-types) or [File/Blob](/docs/rpc-handler#supported-data-types) in responses (requests will auto fall back to the default behavior). To exclude unsupported procedures, use the `exclude` option:
61+
62+
```ts twoslash
63+
import { RPCLink } from '@orpc/client/fetch'
64+
import { BatchLinkPlugin } from '@orpc/client/plugins'
65+
// ---cut---
66+
const link = new RPCLink({
67+
url: 'https://api.example.com/rpc',
68+
plugins: [
69+
new BatchLinkPlugin({
70+
groups: [
71+
{
72+
condition: options => true,
73+
context: {}
74+
}
75+
],
76+
exclude: ({ path }) => {
77+
return ['planets/getImage', 'planets/subscribe'].includes(path.join('/'))
78+
}
79+
}),
80+
],
81+
})
82+
```
83+
84+
## Request Headers
85+
86+
By default, oRPC uses the headers appear in all requests in the batch. To customize headers, use the `headers` option:
87+
88+
```ts twoslash
89+
import { RPCLink } from '@orpc/client/fetch'
90+
import { BatchLinkPlugin } from '@orpc/client/plugins'
91+
// ---cut---
92+
const link = new RPCLink({
93+
url: 'https://api.example.com/rpc',
94+
plugins: [
95+
new BatchLinkPlugin({
96+
groups: [
97+
{
98+
condition: options => true,
99+
context: {}
100+
}
101+
],
102+
headers: () => ({
103+
authorization: 'Bearer 1234567890',
104+
})
105+
}),
106+
],
107+
})
108+
```
109+
110+
## Response Headers
111+
112+
By default, the response headers are empty. To customize headers, use the `headers` option:
113+
114+
```ts twoslash
115+
import { RPCHandler } from '@orpc/server/fetch'
116+
import { router } from './shared/planet'
117+
// ---cut---
118+
import { BatchHandlerPlugin } from '@orpc/server/plugins'
119+
120+
const handler = new RPCHandler(router, {
121+
plugins: [new BatchHandlerPlugin({
122+
headers: responses => ({
123+
'some-header': 'some-value',
124+
})
125+
})],
126+
})
127+
```

0 commit comments

Comments
 (0)