Return JSON Schema
Registry entries may include returnJsonSchema — a JSON Schema draft-07 subset that describes the result field on a successful RpcResponse (the value your handler returns from Return, after serialization).
Unlike params JSON Schema, this is a normal object schema for one payload, not a tuple over args.
What gets validated
For RPC, QA sends args and receives something like:
{
"status": "ok",
"result": { "n": 1, "sku": "abc" },
"label": "ORDER_OK"
}returnJsonSchema applies to result only — not label, returnType, or the HTTP body from ApiReturn.
Register at cat / catModule time (recommended)
Same pattern as params JSON Schema — pass returnJsonSchema in options:
import { cat, Return } from '@gloocan/cat-inspector'
cat(
'Orders.createOrder',
function createOrder(sku: string, qty: number) {
return Return('ORDER_OK', { sku, qty })
},
{
returnJsonSchema: {
type: 'object',
required: ['sku', 'qty'],
properties: {
sku: { type: 'string', minLength: 1 },
qty: { type: 'integer', minimum: 1 },
},
},
},
)With catModule, pass per-method options (key = method name in the module object):
import { catModule, Return } from '@gloocan/cat-inspector'
const summarizeReturnSchema = {
type: 'object',
required: ['name', 'type', 'size', 'headHex16'],
properties: {
name: { type: 'string' },
type: { type: 'string' },
size: { type: 'number', minimum: 0 },
headHex16: { type: 'string' },
},
}
export const QaFileUploadShowcase = catModule(
'QaFileUploadShowcase',
{
async summarizeTopLevelFile(file: File) {
const head = '…'
return Return('FILE_SUMMARY', {
name: file.name,
type: file.type,
size: file.size,
headHex16: head,
})
},
},
{ summarizeTopLevelFile: { returnJsonSchema: summarizeReturnSchema } },
)No separate registerReturnJsonSchema call is required when the schema is known at registration time.
Register later with registerReturnJsonSchema
When the schema lives in a separate file or is generated after registration, attach it after cat / catModule (typical pattern: register-schemas.ts imported from your server entry):
import { registerReturnJsonSchema } from '@gloocan/cat-inspector'
// Service already registered as Orders.createOrder via catModule
registerReturnJsonSchema('Orders.createOrder', {
type: 'object',
required: ['sku', 'qty'],
properties: {
sku: { type: 'string', minLength: 1 },
qty: { type: 'integer', minimum: 1 },
},
})The fnKey must already exist in the registry (ClassName.methodName). Passing null clears the schema.
registerReturnJsonSchema
function registerReturnJsonSchema(
fnKey: string,
schema: Record<string, unknown> | null,
): voidParams + return on the same method
You can set both schemas in one catModule options entry:
catModule(
'Orders',
{
createOrder(sku: string, qty: number) {
return Return('ORDER_OK', { sku, qty })
},
},
{
createOrder: {
paramsJsonSchema: {
type: 'array',
minItems: 2,
maxItems: 2,
items: [
{ type: 'string', minLength: 1 },
{ type: 'integer', minimum: 1 },
],
},
returnJsonSchema: {
type: 'object',
required: ['sku', 'qty'],
properties: {
sku: { type: 'string' },
qty: { type: 'integer', minimum: 1 },
},
},
},
},
)If the handler omits a required return field or returns the wrong types, validation fails after the handler runs (see failure shape below).
Turn on validation at invoke time
Return schema checks are opt-in and require serialization to be enabled:
import { setRpcSerializationConfig } from '@gloocan/cat-inspector'
setRpcSerializationConfig({
enabled: true,
maxUtf8Bytes: 64_000,
validateReturnJsonSchema: true,
})You can also set rpcSerialization on attachCatRPC (see Serialization).
| Flag | Required for return schema? |
|---|---|
enabled: true | Yes — validation runs on the serialized result. |
validateReturnJsonSchema: true | Yes — otherwise returnJsonSchema is ignored. |
With both on:
- Handler returns
Return('OK', { n: 1 })and schema expects{ n: number }→ RPC succeeds. - Handler returns
Return('OK', { n: 'not-a-number' })→ client getsRETURN_SCHEMA_INVALID(handler did run).
With validateReturnJsonSchema: false, a wrong shape still returns status: 'ok' if the handler did not throw.
Validation runs inside executeRPC when the flags above are set; there is no separate public “validate return” helper on the package export surface.
resetReturnJsonSchemaValidators
Clears cached AJV validators — use in tests when schemas change between cases:
import { resetReturnJsonSchemaValidators } from '@gloocan/cat-inspector'
afterEach(() => {
resetReturnJsonSchemaValidators()
})Failure shape on RPC
When validation fails inside executeRPC, the client receives RpcResponse with:
status: 'error'label:RETURN_SCHEMA_INVALIDerror.code:RETURN_SCHEMA_INVALID
The handler has already executed; this is a post-invoke check on the serialized return value.
Params vs return (quick comparison)
| Params schema | Return schema | |
|---|---|---|
| Field on registry | paramsJsonSchema | returnJsonSchema |
| Validates | args[] (tuple) | result (object) |
| When | Before handler runs | After handler runs |
| Enable flag | validateParamsJsonSchema | validateReturnJsonSchema + enabled: true |
| Error code | INPUT_SCHEMA_INVALID | RETURN_SCHEMA_INVALID |
| Typical registration | cat / catModule options or registerParamsJsonSchema | cat / catModule options or registerReturnJsonSchema |
See also
- Params JSON Schema — validate inputs before invoke
- Serialization —
enabled,maxUtf8Bytes, and validation flags