Overview
Start with the invariant, not the product
A semantic layer is a small compiler. It accepts a business query, resolves governed definitions, maps them to physical data, and returns a typed result with lineage. You can build that core before adopting dbt Semantic Layer, Cube, Looker, Stardog, or another provider.
The minimum implementation
- Contract registry — versioned entities, dimensions, measures, grain, owner, and tests.
- Physical mapping — source fields and joins behind each logical name.
- Planner — reject incompatible dimensions or ambiguous paths before execution.
- Compiler — emit one deterministic SPARQL or SQL query from the validated request.
- Result envelope — values plus metric version, source, generated query, and freshness.
- Conformance tests — fixed demo data with exact expected rows, including refund and null cases.
For the shared commerce demo, define order_revenue as the sum of schema:price at Order grain and customer as a groupable dimension reached through ex:placed. The logical request {metric: order_revenue, group_by: customer} should compile to the SPARQL lab below. No dashboard or vendor SDK owns the definition.
A deliberately small architecture
MetricRequest -> Registry -> Planner -> QueryCompiler -> Source
-> Result + lineage
Do not start with natural-language generation, caching, or a universal ontology. First make one metric return the same rows for every consumer. Add adapters only after the contract and conformance fixture are stable.
