Skip to Content

RPC result serialization

When QA runs a service step, the web app sends rpc:call with args and expects a JSON RPC_RESPONSE (result, label, …). Your handler might return a Date, bigint, a class instance, or a very large object. rpcSerialization (type RpcSerializationOptions) tells the SDK how to prepare that traffic: optional checks on inputs, normalize outputs, cap size, and optionally enforce JSON Schema you attached at registration.

Default: everything is off. The handler return value is passed through (the transport still JSON-encodes what it can). Turning options on is opt-in and only affects the RPC path—not real HTTP responses from Express or Postman.

What you get when you enable it

BenefitWhich flag
QA never receives values that break JSON (e.g. bigint, Date, ORM entities)enabled: true
Huge results are rejected before they hit the browserenabled: true + maxUtf8Bytes
Bad test inputs are rejected before your handler runsvalidateParamsJsonSchema: true + paramsJsonSchema on the entry
Handler return shape is checked after invoke (contract tests on the server)enabled: true + validateReturnJsonSchema: true + returnJsonSchema on the entry

Schemas come from cat / catModule options or registerParamsJsonSchema / registerReturnJsonSchema—serialization config only turns enforcement on.

How executeRPC uses rpcSerialization

On each rpc:call, after the function is found and arg count matches the catalog:

  1. Params schema (optional) — if validateParamsJsonSchema is on and the entry has paramsJsonSchema, validate args first. On failure → INPUT_SCHEMA_INVALID (handler not run).
  2. Invoke — run the handler and get the return value.
  3. Serialization (optional) — if enabled, normalize the result to JSON-safe data and enforce maxUtf8Bytes. On failure → RESULT_NOT_SERIALIZABLE.
  4. Return schema (optional) — if enabled and validateReturnJsonSchema and the entry has returnJsonSchema, validate result. On failure → RETURN_SCHEMA_INVALID (handler already ran).
  5. Success — build RPC_RESPONSE with status: 'ok'.

Other errors (FN_NOT_FOUND, WRONG_ARG_COUNT, INVOKE_TIMEOUT, etc.) are unchanged; see RPC error codes.

RpcSerializationOptions

FieldDefaultWhat it does
enabledfalseWhen true, serializeRpcResult deep-clones the handler result into JSON-safe plain data before building RPC_RESPONSE.
maxUtf8Bytes4 * 1024 * 1024 when enabledAfter normalization, JSON.stringify(result) must fit in this UTF-8 budget or RPC returns RESULT_NOT_SERIALIZABLE.
validateParamsJsonSchemafalseBefore invoke, validate args against paramsJsonSchema if present. Does not require enabled.
validateReturnJsonSchemafalseAfter serialization, validate result against returnJsonSchema if present. Requires enabled: true.

Turn it on

On the host (attachCatRPC)

Recommended for cat-demo–style servers:

import { attachCatRPC } from '@gloocan/cat-inspector/socket-io' attachCatRPC(io, { scanRoots: [/* … */], rpcSerialization: { enabled: true, maxUtf8Bytes: 64_000, validateParamsJsonSchema: true, validateReturnJsonSchema: true, }, })

Same object can live under bootstrap: { rpcSerialization: { … } } when you pass nested bootstrap options (attachCatRPC merges them).

Global config (tests or custom gateways)

import { setRpcSerializationConfig } from '@gloocan/cat-inspector' setRpcSerializationConfig({ enabled: true, maxUtf8Bytes: 64_000, validateParamsJsonSchema: true, validateReturnJsonSchema: true, })

resetRpcSerializationConfig clears all flags (used in tests).

Enabled vs disabled (plain examples)

enabled: false (default)

  • Handler returns Return('OK', { at: new Date() }) → client may get a non-ISO date shape or encoding quirks depending on the transport.
  • returnJsonSchema on the registry entry is ignored even if validateReturnJsonSchema: true.

enabled: true

  • Same handler → result.at is an ISO string in RPC_RESPONSE.
  • Class instances, Map, functions in the return tree → RESULT_NOT_SERIALIZABLE (handler ran; RPC response is an error).

validateParamsJsonSchema: true

  • QA sends args: [''] but schema requires non-empty string → INPUT_SCHEMA_INVALID before invoke.

validateReturnJsonSchema: true (with enabled: true)

  • Handler returns Return('OK', { n: 'text' }) but schema expects { n: number }RETURN_SCHEMA_INVALID after invoke.

Serialization rules (serializeRpcResult)

When enabled is true, the SDK:

  • Allows: null, boolean, number, string, arrays, plain objects (Object or null prototype)
  • Converts: bigint → decimal string, Date → ISO string, nested undefined in objects omitted; root undefinednull
  • Rejects: functions, symbols, class instances, Map/Set, circular references

Use maybeSerializeRpcResult if you need { ok, value | message } without throwing. Inside executeRPC, failures map to RESULT_NOT_SERIALIZABLE.

API reference

FunctionDescription
setRpcSerializationConfig(partial)Merge into global options; sets default maxUtf8Bytes when enabling.
getRpcSerializationConfig()Read-only snapshot.
resetRpcSerializationConfig()Sets enabled: false and turns off both schema flags.
serializeRpcResult(raw)Normalize one value; throws SerializeRpcResultError (code: RESULT_NOT_SERIALIZABLE).
maybeSerializeRpcResult(raw)Same as above but returns { ok: true, value } or { ok: false, message }.

See also