schema¶
A stored message carries a dataschema. Three years later somebody has to answer what shape was
this?, and the answer must be the same one a consumer would have got the day the message was
written.
That is the whole job. Everything else here follows from it.
reg, err := schema.Embed(schema.Schema{
URN: urn.Schema{Name: "orders.created", Version: 3},
Language: schema.JSONSchema,
Bytes: ordersCreated, // //go:embed schemas/orders.created.v3.json
})
guard := schema.NewGuard(reg, []schema.Validator{jsonschema.New()})
err = guard.Validate(ctx, event.DataSchema, event.Data)
Three properties worth knowing before anything else¶
A published identifier cannot change
Republishing the same URN with different bytes is refused. Without that, a consumer that
validated a message yesterday cannot reproduce the result today, and every stored dataschema
becomes a claim about something that has since moved.
It resolves offline. A service embeds its schemas and validates without a network call. A service that must reach the registry to validate has taken a runtime dependency on it, which is what a registry should most avoid being.
It fails open, and says so in a number. A dataschema that cannot be resolved does not stop the
message; it increments a counter. A registry outage is a degradation, not an outage of everything
downstream — and the counter is what stops that being silent.
Start here¶
-
Embed a schema, validate a payload, and see the fail-open counter move.
-
The offline path, which is the one nearly every service wants.
-
Four endpoints. Why they are not Confluent's.
-
The asymmetry: unresolvable fails open, non-conforming fails closed.
Not built yet, and honestly labelled¶
There is no compatibility checking. A version bump asserts only that the bytes differ; it is not a compatibility claim and nothing should read it as one.
The gap is shaped rather than left open: the publish API
already takes a compatibility mode, a Checker interface already exists per language, and the store
already keeps prior versions. When a checker arrives it is an implementation, not a refactor of
every call site.