Skip to content

PATTERN Cited by 1 source

Model once, represent everywhere

Pattern

Promote your conceptual model from documentation / tribal knowledge to a first-class control-plane artifact, then project that single authored model into every concrete surface that needs to know about the concept — schemas (GraphQL, Avro, SQL, RDF, Java), APIs, UIs, pipelines, authoring tools.

One authored source → many generated representations. No manual re-encoding per surface.

This is the pattern Netflix names in its UDA post title:

"We need new foundations that allow us to define a model once, at the conceptual level, and reuse those definitions everywhere. But it isn't enough to just document concepts; we need to connect them to real systems and data. And more than just connect, we have to project those definitions outward, generating schemas and enforcing consistency across systems. The conceptual model must become part of the control plane." — Netflix, Model Once, Represent Everywhere: UDA (sources/2025-06-14-netflix-model-once-represent-everywhere-uda)

Problem it solves

The failure mode the pattern rejects is concept-drift across independent encodings:

  • System A encodes actor in one GraphQL schema.
  • System B encodes it in a different Avro record.
  • System C defines its own SQL table.
  • The warehouse has its own dim_actor with a different ID scheme.
  • Every team thinks they have the canonical actor.

Consequences: duplicated models, inconsistent terminology, silent data-quality discrepancies across microservices, and effectively-zero cross-system connectivity. Netflix's UDA post enumerates these as the four pain points that motivated the pattern.

Mechanism

  1. Author one conceptual model per domain. In UDA, this is an Upper domain model — a controlled vocabulary of keyed entities + attributes + relationships + taxonomies authored against a shared metamodel.

  2. Treat the model as data, not code. Store it in a substrate where it is introspectable + queryable + versionable — a knowledge graph in UDA's case.

  3. Transpile downward. Use a pipeline (patterns/schema-transpilation-from-domain-model) that generates each downstream surface from the model. UDA names GraphQL, Avro, SQL, RDF, and Java as projection targets.

  4. Auto-provision side effects. Data products in the warehouse, GraphQL APIs on the federated gateway, UIs for authoring, data-movement pipelines between containers — all auto-provisioned from the model + the mappings that connect it to systems.

  5. Make the model a control-plane artifact. Changes to the model re-trigger projections; models are the source of truth for all downstream surfaces.

Canonical instances on this wiki

All three instances apply the same pattern at different altitudes — domain data, API surfaces, deploy artifacts. The pattern is substrate-agnostic.

Enablers — what has to be true for this to work

  1. A sufficiently expressive metamodel. The input language must be rich enough to capture every downstream surface's shape. In UDA this is Upper; in Cloudflare's case it's their TypeScript schema with CLI/SDK/Terraform/MCP extensions.
  2. A transpiler family, not a one-off generator. You need one transpiler per target; the family is the real investment.
  3. Conservative extension under composition. Multiple teams adding domain models cannot break each other's projections.
  4. Tooling for the authored model as data. Introspection, diff, query — so the source of truth is itself manipulable.
  5. Commitment to the model as control-plane. Drift between the model + surfaces must be rejected by the system (CI / reprojection), not ad-hoc tolerated.

Failure modes to plan for

  • Leaky abstraction on one target. One surface needs a feature the metamodel can't express → everyone wants to side-channel it → the "one source of truth" is now two.
  • Transpiler bugs shipping to N surfaces at once. A regression in the generator can silently break many schemas. Regression testing on outputs matters.
  • Model evolution needs discipline. If the model is authored as data + freely edited, you still need the discipline of schema-evolution / backward-compatibility review — UDA's answer is the conservative-extension property.
  • The model becomes the bottleneck. If every change needs to go through one team, the model owner becomes a critical path for product work. Cloudflare's answer: TypeScript-as-codegen + self-serve. UDA's answer: Upper federation + domain-team ownership of per-domain named graphs.

Seen in

Last updated · 319 distilled / 1,201 read