Input/Output Structure
oRPC allows you to control the organization of request inputs and response outputs using the inputStructure
and outputStructure
options. This is especially useful when you need to handle parameters, query strings, headers, and body data separately.
Input Structure
The inputStructure
option defines how the incoming request data is structured.
Compact Mode (default)
Combines path parameters with query or body data (depending on the HTTP method) into a single object.
const compactMode = os.route({
path: '/ping/{name}',
method: 'POST',
})
.input(z.object({
name: z.string(),
description: z.string().optional(),
}))
Detailed Mode
Provide an object whose fields correspond to each part of the request:
params
: Path parameters (Record<string, string> | undefined
)query
: Query string data (any
)headers
: Headers (Record<string, string | string[] | undefined>
)body
: Body data (any
)
const detailedMode = os.route({
path: '/ping/{name}',
method: 'POST',
inputStructure: 'detailed',
})
.input(z.object({
params: z.object({ name: z.string() }),
query: z.object({ search: z.string() }),
body: z.object({ description: z.string() }).optional(),
headers: z.object({ 'x-custom-header': z.string() }),
}))
Output Structure
The outputStructure
option determines the format of the response based on the output data.
Compact Mode (default)
Returns the output data directly as the response body.
const compactMode = os
.handler(async ({ input }) => {
return { message: 'Hello, world!' }
})
Detailed Mode
Returns an object with these optional properties:
status
: The response status (must be in 200-399 range) if not set fallback tosuccessStatus
.headers
: Custom headers to merge with the response headers (Record<string, string | string[] | undefined>
).body
: The response body.
const detailedMode = os
.route({ outputStructure: 'detailed' })
.handler(async ({ input }) => {
return {
headers: { 'x-custom-header': 'value' },
body: { message: 'Hello, world!' },
}
})
const multipleStatus = os
.route({ outputStructure: 'detailed' })
.output(z.union([ // for openapi spec generator
z.object({
status: z.literal(201).describe('record created'),
body: z.string()
}),
z.object({
status: z.literal(200).describe('record updated'),
body: z.string()
}),
]))
.handler(async ({ input }) => {
if (something) {
return {
status: 201,
body: 'created',
}
}
return {
status: 200,
body: 'updated',
}
})
Initial Configuration
Customize the initial oRPC input/output structure settings using .$route
:
const base = os.$route({ inputStructure: 'detailed' })