PATTERN Cited by 1 source
Schema transpilation from domain model¶
Pattern¶
Treat your conceptual domain model as the authored source and transpile it, mechanically + semantically-faithfully, into every concrete schema language your organisation uses — GraphQL, Avro, SQL, RDF, Java, Protobuf, OpenAPI, whatever. One transpiler per target language; one authored source per domain.
Netflix's UDA post puts this precisely:
"Transpile domain models into schema definition languages like GraphQL, Avro, SQL, RDF, and Java, while preserving semantics." — UDA, "Using UDA, users and systems can…" (sources/2025-06-14-netflix-model-once-represent-everywhere-uda)
The key word is "preserving semantics" — the transpiled schemas must not drift from the domain model's intended meaning; a round-trip interpretation through any target must resolve to the same underlying concept in the domain model.
Mechanism¶
-
Fixed authoring substrate. All domain models are authored in one metamodel — Upper in UDA (systems/netflix-upper). Every domain is a conservative extension of the metamodel.
-
One transpiler per target language. Each transpiler consumes the same domain-model shape and emits a concrete schema in its target language. UDA's family:
| Target | Produces | Used for |
|---|---|---|
| GraphQL | Type definitions + field resolvers | Federated APIs on the Enterprise Gateway |
| Avro | Record schemas | Warehouse data products + Data Mesh |
| SQL | Table / view definitions | Warehouse queries (cf. Sphere) |
| RDF | .ttl / triple vocabulary |
Graph-native query + validation |
| Java | Jena-based Java API | Embedded use, including by UDA's UI |
-
Semantic preservation rules. The metamodel's primitives (keyed entity / attribute / relationship / taxonomy / datatype) map by fixed rules to constructs in each target — the transpiler encodes this mapping. Domain authors don't write target-specific hacks; edge cases are resolved at the metamodel / transpiler level.
-
Bundled pipeline + schema generation. The same source also produces data-movement pipelines: "Move data faithfully between data containers, such as from federated GraphQL entities to Data Mesh, CDC sources to joinable Iceberg Data Products." Schema + pipeline are projected together.
-
Sink auto-provisioning. In UDA's PDM use case, the transpiled Avro + GraphQL schemas auto-provision the warehouse data product + the gateway API — no ticket, no hand-wiring (systems/netflix-pdm).
Why this is non-trivial¶
The classical alternative — one schema language per target + hand-maintained consistency — fails at enterprise scale because:
- N × M problem. N systems × M target languages of contracts to maintain. Each change touches an unbounded number of files.
- Subtle inconsistencies. Someone eventually encodes
movieslightly differently in GraphQL and Avro; downstream analytics breaks; no-one's to blame. - No introspection. You can't ask "how is
actordefined across the company?" because the source of truth is spread across many languages.
Transpiling from a single domain model collapses N × M to N (one per domain) + M (one transpiler per target) — a linear total investment that composes.
Requirements / when to use¶
- You already have a metamodel rich enough to express every target's shape without special-casing. UDA built Upper explicitly as a "strict subset of W3C semantic technologies tailored and generalised for domain modelling" to hit this bar.
- The transpilers are owned as a family — adding a new target is adding a new transpiler, not negotiating with each existing consumer.
- Your organisation commits to treating the domain model as the control-plane artifact for all projected schemas (patterns/model-once-represent-everywhere).
Not to be confused with¶
- patterns/gradual-transpiler-migration — Figma's transpiler pattern is for migrating between source languages (a one-shot one-way-door migration). Schema transpilation from a domain model is a continuous projection pipeline, not a migration.
- patterns/schema-driven-interface-generation — Cloudflare's version is a sibling pattern at the API surface layer (CLI
- SDK + Terraform + MCP from one TypeScript schema). UDA's version is at the data model layer. Both are instances of patterns/model-once-represent-everywhere.
- One-off IDL generators (e.g. hand-written
avro-toolswrappers). Schema transpilation from a domain model is the fixed-point, not an ad-hoc generator.
Caveats¶
- Expressiveness gaps. The metamodel must express every target's meaningful features. If Avro's union types or GraphQL's interface unions can't be cleanly expressed in the metamodel, authors will work around it.
- Evolution discipline. Changes to the metamodel or a domain model reproject all targets; the blast radius of a mistake is large. UDA uses conservative extension to constrain the blast radius structurally.
- Target-side ergonomics. Generated code in each target must still feel idiomatic to that target's consumers. Transpiler quality decides whether the pattern is loved or resented by users.
- No public benchmarks. The Netflix UDA post doesn't disclose transpiler compile times, generated-schema LOC, or change frequency.
Seen in¶
- sources/2025-06-14-netflix-model-once-represent-everywhere-uda — Netflix UDA's transpiler family (GraphQL, Avro, SQL, RDF, Java) is the wiki's canonical instance.
Related¶
- systems/netflix-uda · systems/netflix-upper · systems/netflix-pdm — the deployment.
- concepts/domain-model · concepts/metamodel · concepts/data-container — the authored input + targets.
- concepts/semantic-interoperability — the goal transpilation serves.
- patterns/model-once-represent-everywhere — the overarching pattern.
- patterns/self-referencing-metamodel-bootstrap — the metamodel shape that makes a transpiler family stable.
- patterns/schema-driven-interface-generation — sibling at the API-surface layer.
- patterns/gradual-transpiler-migration — adjacent but distinct pattern (migration, not continuous projection).