Skip to main content

MessagePack Schemas

MessagePack is a compact binary serialisation format that encodes JSON-like data structures in a smaller, faster form. In MAPS, it is treated as “binary JSON with a strict type system,” backed by a schema in SchemaConfig.


1. Description

MessagePack encodes:

  • integers (signed and unsigned)
  • floating point numbers
  • strings (UTF-8)
  • binary blobs
  • arrays
  • maps
  • booleans and nil

Compared to JSON:

  • more compact on the wire
  • no quoting overhead
  • native binary type
  • deterministic encoding options

In MAPS, MessagePack payloads are decoded into Typed Events using a JSON-based schema held in SchemaConfig.schema.


2. Schema Format

MAPS represents MessagePack schemas using JSON Schema inside the schema field of SchemaConfig, just like JSON and CBOR.

Example Schema

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"deviceId": {
"type": "string",
"description": "Logical device identifier"
},
"temperature": {
"type": "number",
"minimum": -40,
"maximum": 85,
"x-precision": 1,
"description": "Unit: °C"
},
"humidity": {
"type": "number",
"minimum": 0,
"maximum": 100,
"x-precision": 1,
"description": "Unit: %RH"
},
"pressure": {
"type": "number",
"minimum": 300,
"maximum": 1100,
"x-precision": 1,
"description": "Unit: hPa"
},
"battery": {
"type": "integer",
"minimum": 0,
"maximum": 100,
"description": "Unit: %"
},
"timestamp": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 UTC timestamp"
}
},
"required": [
"deviceId",
"temperature",
"humidity",
"pressure"
]
}

3. SchemaConfig Example

A SchemaConfig for a MessagePack-encoded environmental sensor payload:

{
"versionId": "1",
"name": "EnvSensor-MessagePack",
"description": "Environmental sensor schema using MessagePack encoding.",
"labels": {
"uniqueId": "f610f39b-3aac-4fb7-9b2a-8ce784a2b123",
"resource": "sensor",
"interface": "sensor.env.msgpack",
"comments": "MessagePack-encoded environmental telemetry"
},
"format": "messagepack",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"deviceId": {
"type": "string",
"description": "Logical device identifier"
},
"temperature": {
"type": "number",
"minimum": -40,
"maximum": 85,
"x-precision": 1,
"description": "Unit: °C"
},
"humidity": {
"type": "number",
"minimum": 0,
"maximum": 100,
"x-precision": 1,
"description": "Unit: %RH"
},
"pressure": {
"type": "number",
"minimum": 300,
"maximum": 1100,
"x-precision": 1,
"description": "Unit: hPa"
},
"battery": {
"type": "integer",
"minimum": 0,
"maximum": 100,
"description": "Unit: %"
},
"timestamp": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 UTC timestamp"
}
},
"required": [
"deviceId",
"temperature",
"humidity",
"pressure"
]
}
}

Key points:

  • format must be "messagepack".
  • schema carries the JSON Schema describing the logical structure.
  • labels.resource and labels.interface can be used to expose this over CoAP (rt / if) or for discovery.

4. Java Usage

4.1 Registering the Schema

SchemaConfig config = SchemaConfig.builder()
.name("EnvSensor-MessagePack")
.format("messagepack")
.schema(schemaJsonObject)
.build();

schemaRepository.register(config);

4.2 Processing MessagePack Payloads

At runtime, MAPS:

  1. Resolves the SchemaConfig based on topic/context.
  2. Decodes the MessagePack payload into a generic object tree.
  3. Validates and normalises the tree using the schema:
    • numeric ranges (minimum, maximum)
    • required fields
    • type checks
  4. Builds a Typed Event:
    • typed fields
    • canonical timestamp (epoch millis)
  5. Passes the Typed Event through:
    • filtering
    • transformations
    • statistics
    • format conversions (e.g. MessagePack → JSON / Avro / Protobuf)

Encoding works in reverse: Typed Events are serialised to MessagePack using the schema as a guide.


5. MessagePack-Specific Notes

  • Binary data
    MessagePack supports a native bin type; schema fields using binary payloads should be modelled as:

    { "type": "string", "contentEncoding": "base64" }

    or with a format your tooling understands. MAPS can still treat the underlying bytes natively.

  • Numeric types
    MessagePack has multiple integer and float widths. MAPS normalises them to Java numeric types (int, long, double) based on value range.

  • Timestamps
    MessagePack has a timestamp extension type; MAPS maps those to epoch millis, or uses string date-time fields as defined in the schema.

  • Maps and arrays
    Arrays and maps behave like JSON arrays and objects.
    Use JSON Schema items and properties to define their shapes.

  • Deterministic encoding
    For hashing or signing, you should use a consistent field ordering in the schema and the same encoder configuration on the producing side.


MessagePack in MAPS behaves just like JSON/CBOR from a schema point of view; the only real difference is that the wire format is binary and smaller.