Skip to main content
Version: dev

Schema Evolution

Schema evolution lets different versions of your service exchange messages safely — a v2 writer can produce a message a v1 reader still understands, and vice versa.

Two Modes

  • Schema-consistent mode (default): more compact, but both sides must have exactly the same schema. Good when all services update together.
  • Compatible mode: writes extra field metadata so readers can skip unknown fields and tolerate missing ones. Good for independent deployments or rolling upgrades.

Enable Compatible Mode

const fory = new Fory({ compatible: true });

Use this when:

  • services deploy schema changes independently
  • older readers may see newer payloads
  • newer readers may see older payloads from before a field was added

Example

Writer schema:

const writerType = Type.struct(
{ typeId: 1001 },
{
name: Type.string(),
age: Type.int32(),
},
);

Reader schema with fewer fields:

const readerType = Type.struct(
{ typeId: 1001 },
{
name: Type.string(),
},
);

With compatible: true, the reader ignores fields it does not know about, and fills unknown fields with default values.

Opting Out of Evolution for One Struct

You can disable evolution metadata for a specific struct even inside a compatible: true instance:

const fixedType = Type.struct(
{ typeId: 1002, evolving: false },
{
name: Type.string(),
},
);

evolving: false produces smaller messages for that struct, but both the writer and reader must agree on this setting. If one side writes with evolving: false and the other reads expecting compatible metadata, deserialization will fail.

When to Use Each Mode

Schema-consistentCompatible
Services always update together✔ best choiceworks, but wasteful
Independent deploymentswill break✔ best choice
Smallest possible messagesslightly larger
Rolling upgradesrisky✔ safe

Cross-Language Requirement

Compatible mode only protects you from schema differences in the fields of a type. You still need the same type identity (same numeric ID or same namespace + typeName) on every side. See Cross-Language.