ManifestCompatibility
Compares two Manifests and classifies every difference of the wire contract as ChangeKind.ADDITIVE or ChangeKind.BREAKING. Entries are matched by name: a removed context, aggregate, command, event, route, lifecycle command, query model, subscription, published stream or error code is breaking, an added one additive. A command or an event renamed with its former name in its aliases keeps matching: the rename is additive, though the routes the old name gave are reported removed.
An event removed and listed in the aggregate's
retiredevents (@AggregateRoot(retiredEvents)) is retired, which is additive, when each of its stored names (its name and aliases) is retired; one removed without that breaks the loading of its history. A name no longer retired breaks too; one newly retired is additive.Schemas follow SchemaCompatibility: a removed field, a narrowed type, a newly required field or a removed enum value break; an optional field or an enum value added does not. A state and an event are outputs as well (SchemaDirection.OUTPUT): their readers (the query models' clients, the published stream's subscribers) read what the service writes now, so a field made optional or nullable, a type widened or an enum value added breaks an aggregate that has readers, whatever the revision, which only rebuilds or upgrades the service's own records. The state schema is the snapshot query's fields, so the same rules hold for it, and a field renamed with its old path in
x-wow-aliasis additive.A revision covers only the service's own storage, never a contract others read. A state schema that breaks breaks the snapshot query's clients (its
state.*fields) and the subscribers of the aggregate's published stream when it carries the state, whatever the state revision: raising it (@AggregateRoot (stateRevision)) only rebuilds the stored snapshots from the log, so it keeps the contract only for an aggregate with neither. Likewise an event schema that breaks breaks the events query's clients and the published stream's subscribers, which read events at their current revision: raising the revision (with an@Upgradefrom each earlier one) only reads the service's own old records. A lowered revision breaks.A service route (ServiceRouteManifest) is matched by its name: removing it, or changing its method or path, breaks; a parameter (named by where it is read from and its name,
query:limit) removed, retyped or made required breaks, and so does a required one added; one moved between the path and the query is one removed and one added; its request is an input and its response an output (SchemaDirection); a route that no longer takes or answers a body, or newly does, breaks. Its refusal codes are documentation for a client that handles unknown codes, so a code added or removed is additive.Command creation that accepts more (
NONEorREQUIREDtoALLOWED) is additive, any other change breaking; a produced event removed breaks a client waiting for it.A command made internal (
@InternalCommand) breaks: the public port no longer serves its routes, which its public clients send. One made public again is additive: the internal port, and the services that call it, keep its routes either way.Changing an aggregate's id source (
@AggregateRoot(idSource)) either way breaks: a route by no id, the caller's own aggregate's for one whose id is its owner's, means another aggregate, and the ids its clients send or keep change meaning. The routes by no id the change adds or removes are part of it, reported once with it; any other route follows the rules above.An aggregate's access attribute (
@Access) removed or renamed breaks the access policies and the stored records that name it, and so does one whose type changes or that changes between one value and several; one added is additive.Disabling snapshots, changing the ownership, a published stream's topic, or dropping its state breaks; so does a subscription changing its kind, function or source stream, no longer deriving a command, or an
@OnRejected/@OnCommittedhandler no longer taking a command's receipts; a removed@OnCommittedhandler is a removed subscription, and an added one additive.Descriptions, the state fingerprint (derived from the schema), query indexes, schedules, retry budgets and start positions are not contract and are not compared.