Skip to Content

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.

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, ): void

Params + 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).

FlagRequired for return schema?
enabled: trueYes — validation runs on the serialized result.
validateReturnJsonSchema: trueYes — 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 gets RETURN_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_INVALID
  • error.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 schemaReturn schema
Field on registryparamsJsonSchemareturnJsonSchema
Validatesargs[] (tuple)result (object)
WhenBefore handler runsAfter handler runs
Enable flagvalidateParamsJsonSchemavalidateReturnJsonSchema + enabled: true
Error codeINPUT_SCHEMA_INVALIDRETURN_SCHEMA_INVALID
Typical registrationcat / catModule options or registerParamsJsonSchemacat / catModule options or registerReturnJsonSchema

See also