For the complete documentation index, see llms.txt. This page is also available as Markdown.

Data Contracts

This article assumes you've completed the Getting Started guide and understand the data modeling concepts.

Data contracts are the enforcement mechanism that makes data models mandatory. Without a contract, models are just documentation - contracts make validation happen.

Overview

In the component chain, contracts sit between models and execution:

Payload Shapes → Data Models → Data Contracts → Data Flows

                              Enforcement happens here

When you specify a data contract in a bridge, the UNS output plugin validates every message against the associated model.

UI Capabilities

The Management Console provides read-only access to contracts:

Feature
Available
Notes

View contract list

Shows all contracts with their models

Filter/search

Filter by name, instance, or model

View associations

See which model version each contract enforces

View usage

Shows count of stream processors using contract

Create contracts

Auto-created when creating models in UI

Edit contracts

Immutable once created

Delete contracts

Must be done via config.yaml

Contracts List

What you see in the UI:

  • Name: Contract identifier (e.g., _cnc_v1, _pump_v2)

  • Instance: Which UMH Core instance owns the contract

  • Model: The model and version being enforced (e.g., cnc (v1))

  • Stream Processors: Count of processors using this contract

Auto-Creation via UI

When you create a model in the UI, it automatically generates a matching contract:

  1. Create model pump version v1 in UI

  2. System auto-creates contract _pump_v1

  3. Contract immediately available for use in bridges

Configuration

Access configuration via: Instances → Select instance → ... → Config File

Basic Structure

Naming Convention

Contracts follow the pattern _modelname_version:

  • Always start with underscore

  • Include model name

  • End with version number

  • Examples: _pump_v1, _temperature_sensor_v2, _workorder_v1

Enforcement Mechanism

Where Validation Happens

The UNS output plugin (output: uns: {}) performs validation:

  1. Reads metadata: Extracts data_contract from message

  2. Looks up contract: Finds the associated model

  3. Validates structure: Checks topic path matches model

  4. Validates payload: Ensures data types match shapes

  5. Result:

    • ✅ Valid → Message published to topic

    • ❌ Invalid → Message rejected, bridge degraded

Validation Failures

When validation fails:

Result:

  • Message rejected (not published)

  • Bridge enters degraded state

  • Error logged with details

  • Bridge retries with backoff

Contract Types

The Special _raw Contract

  • Accepts any structure

  • No validation performed

  • Use for exploration and development

  • Bridge never goes degraded from data issues

Model-Based Contracts

  • Enforces exact model structure

  • Validates data types via payload shapes

  • Rejects non-conforming messages

  • Use for production systems

Relationship to Data Types

Data Type
Common Contracts
Validation

Raw/Exploration

_raw

No validation

Device Models

_pump_v1, _sensor_v1, _cnc_v1

Model-based validation

Business Models

_workorder_v1, _maintenance_v1

Always strict

Examples

Simple Device Contract

Relationship to Stream Processors

Stream processors don't use contracts directly - they reference models:

However, if a matching contract exists (_pump_v1), the stream processor's output will be validated against it automatically.

Last updated