Pino Logging Integration docs
Easy add structured logging, request tracking, and error monitoring to your oRPC powered by Pino
const logger = pino()
const handler = new RPCHandler(router, {
plugins: [
new LoggingHandlerPlugin({
logger, // Custom logger instance
generateId: ({ request }) => crypto.randomUUID(), // Custom ID generator
logRequestResponse: true, // Log request start/end (disabled by default)
logRequestAbort: true, // Log when requests are aborted (disabled by default)
}),
],
})Ratelimit Helpers docs
The Rate Limit package provides flexible rate limiting for oRPC with multiple storage backend support. It includes adapters for in-memory, Redis, and Upstash, along with middleware and plugin helpers for seamless integration.
Ratelimiter
const ratelimiter = new MemoryRatelimiter({
maxRequests: 10,
window: 60000,
})Manually usage
const result = await limiter.limit('user:123')
if (!result.success) {
throw new ORPCError('TOO_MANY_REQUESTS', {
data: {
limit: result.limit,
remaining: result.remaining,
reset: result.reset,
},
})
}Built-in middleware
const loginProcedure = os
.$context<{ ratelimiter: Ratelimiter }>()
.input(z.object({ email: z.email() }))
.use(
createRatelimitMiddleware({
limiter: ({ context }) => context.ratelimiter,
key: ({ context }, input) => `login:${input.email}`,
}),
)
.handler(({ input }) => {
return { success: true }
})
const result = await call(
loginProcedure,
{ email: 'user@example.com' },
{ context: { ratelimiter } }
)Response Header Plugin
import { RatelimitHandlerPlugin } from '@orpc/experimental-ratelimit'
const handler = new RPCHandler(router, {
plugins: [
new RatelimitHandlerPlugin(),
],
})Retry After Plugin docs
The Retry After Plugin automatically retries requests based on server Retry-After headers. This is particularly useful for handling rate limiting and temporary server unavailability.
import { RetryAfterPlugin } from '@orpc/client/plugins'
const link = new RPCLink({
url: 'http://localhost:3000/rpc',
plugins: [
new RetryAfterPlugin({
condition: (response, options) => {
// Override condition to determine if a request should be retried
return response.status === 429 || response.status === 503
},
maxAttempts: 5, // Maximum retry attempts
timeout: 5 * 60 * 1000, // Maximum time to spend retrying (ms)
}),
],
})Expand support union/interaction in openapi generator
Now you can use union/interaction for define params, query, headers, ...
const procedure = os
.route({ path: '/{type}' })
.input(z.discriminatedUnion('type', [
z.object({
type: z.literal("a"),
foo: z.number().int().positive(),
}),
z.object({
type: z.literal("b"),
foo: z.number().int().negative(),
}),
]))🚀 Features
- client: Retry After Plugin - by @unnoq in #1190 (0ab5a)
- openapi: Expand support for unions/intersection of objects when generating OpenAPI specs - by @unnoq in #1178 (6424b)
- pino: Logging Plugin - by @unnoq in #1191 (4b03c)
- server: Ratelimit helpers & plugins - by @unnoq in #1183 (33122)
Tip
If you find oRPC valuable and would like to support its development, you can do so here.