UNPKG

@trpc/client

Version:

The tRPC client library

193 lines (152 loc) • 5.75 kB
# HTTP Batch Link > A terminating link that batches concurrent tRPC calls into a single HTTP request From https://trpc.io/docs/client/links/httpBatchLink `httpBatchLink` is a [**terminating link**](https://trpc.io/docs/client/links#the-terminating-link) that batches an array of individual tRPC operations into a single HTTP request that's sent to a single tRPC procedure. ## Usage You can import and add the `httpBatchLink` to the `links` array as such: ```ts no-check title="client/index.ts" import { createTRPCClient, httpBatchLink } from '@trpc/client'; import type { AppRouter } from './server'; const client = createTRPCClient<AppRouter>({ links: [ httpBatchLink({ url: 'http://localhost:3000', // transformer, }), ], }); ``` After that, you can make use of batching by setting all your procedures in a `Promise.all`. The code below will produce exactly **one** HTTP request and on the server exactly **one** database query: ```ts no-check const somePosts = await Promise.all([ trpc.post.byId.query(1), trpc.post.byId.query(2), trpc.post.byId.query(3), ]); ``` ## `httpBatchLink` Options The `httpBatchLink` function takes an options object that has the `HTTPBatchLinkOptions` shape. ```ts no-check export interface HTTPBatchLinkOptions extends HTTPLinkOptions { /** * Maximum length of HTTP URL allowed before operations are split into multiple requests * @default Infinity */ maxURLLength?: number; /** * Maximum number of operations allowed in a single batch request * @default Infinity */ maxItems?: number; } export interface HTTPLinkOptions { url: string | URL; /** * Add ponyfill for fetch */ fetch?: typeof fetch; /** * Data transformer * @see https://trpc.io/docs/server/data-transformers **/ transformer?: DataTransformerOptions; /** * Headers to be set on outgoing requests or a callback that of said headers * @see https://trpc.io/docs/client/headers */ headers?: | HTTPHeaders | ((opts: { opList: NonEmptyArray<Operation> }) => HTTPHeaders | Promise<HTTPHeaders>); /** * Send all requests as POST requests regardless of the procedure type * The server must separately allow overriding the method. See: * @see https://trpc.io/docs/rpc */ methodOverride?: 'POST'; } ``` ## Setting a maximum URL length When sending batch requests, sometimes the URL can become too large causing HTTP errors like [`413 Payload Too Large`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413), [`414 URI Too Long`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/414), and [`404 Not Found`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404). The `maxURLLength` option will limit the number of requests that can be sent together in a batch. ```ts no-check title="client/index.ts" import { createTRPCClient, httpBatchLink } from '@trpc/client'; import type { AppRouter } from './server'; const client = createTRPCClient<AppRouter>({ links: [ httpBatchLink({ url: 'http://localhost:3000', maxURLLength: 2083, // a suitable size // alternatively, you can make all RPC-calls to be called with POST (also requires `allowMethodOverride: true` on the server) // methodOverride: 'POST', }), ], }); ``` ## Limiting batch size ### 1. Set a maximum batch size on your server: `maxBatchSize` limits how many operations may be sent in a single batch request. Requests exceeding this limit will be rejected with a `400 Bad Request` error. This can be passed to any tRPC adapter. ```ts no-check title="server.ts" import { createHTTPServer } from '@trpc/server/adapters/standalone'; import { appRouter } from './router'; createHTTPServer({ router: appRouter, maxBatchSize: 10, }); ``` or for example if using Next.js: ```ts no-check title="pages/api/trpc/[trpc].ts" import { createNextApiHandler } from '@trpc/server/adapters/next'; import { appRouter } from '../../../router'; export default createNextApiHandler({ router: appRouter, maxBatchSize: 10, }); ``` ### 2. Set a matching limit on the client: Use the `maxItems` option on your batch link to ensure the client doesn't exceed the server's limit. This splits large batches into multiple HTTP requests automatically ```ts title="client/index.ts" import { createTRPCClient, httpBatchLink } from '@trpc/client'; import type { AppRouter } from '../server'; const client = createTRPCClient<AppRouter>({ links: [ httpBatchLink({ url: 'http://localhost:3000', // 👇 should be the same or lower than the server's maxBatchSize maxItems: 10, }), ], }); ``` ## Disabling request batching ### 1. Disable `batching` on your server: ```ts no-check title="server.ts" import { createHTTPServer } from '@trpc/server/adapters/standalone'; import { appRouter } from './router'; createHTTPServer({ router: appRouter, // 👇 disable batching allowBatching: false, }); ``` or, if you're using Next.js: ```ts no-check title="pages/api/trpc/[trpc].ts" import { createNextApiHandler } from '@trpc/server/adapters/next'; import { appRouter } from '../../../router'; export default createNextApiHandler({ router: appRouter, // 👇 disable batching allowBatching: false, }); ``` ### 2. Replace `httpBatchLink` with [`httpLink`](https://trpc.io/docs/client/links/httpLink) in your tRPC Client ```ts no-check title="client/index.ts" import { createTRPCClient, httpLink } from '@trpc/client'; import type { AppRouter } from './server'; const client = createTRPCClient<AppRouter>({ links: [ httpLink({ url: 'http://localhost:3000', }), ], }); ``` With Next.js, it's the same: swap the link in the `createTRPCClient` you pass to `TRPCProvider`.