Structured Entity Data

Status: DRAFT

Modular‘s Entity model allows for the storage and retrieval of an Entity’s data that adheres to a specific contract used to translate content to and from structured data. The contract for a view of the structured data is identified by a key for a type that can be any string value. Generally the keys are URLs or a reverse-DNS string that signals who owns the contract and where to find its definition.

The translation between an Entity‘s raw content and it’s structured data is a run-time construct. An Entity's FIDL interface allows access to raw content for a given type but the decoding of that data happens within the client process. How an Entity client decodes and encodes structured data is not enforced directly at the FIDL interfaces.

Versioning

It's important to note that Entity clients using the same type key expect the structured data to have the same exact contract. Versioning is not directly supported but versioning information can be added to the type key if needed. When versioning is required the following pattern might be useful.

  • Non-versioned type: “com.fuchsia.color” the contract can and will break hurting compatibility unless all client usage is simultaneously updated. This might be okay or desireable for some in-tree development.
  • Versioned type: “com.fuchsia.v1.color”, the contract is pinned to “v1” in this case. There is an expectation that compatibility can be maintained or upgrade pain mitigated by the owner adding a new type key for updates, e.g. “com.fuchsia.v2.color”

Schemas

For projects in the //topaz layer most of the contracts for structured Entity data are implemented as library code available in //topaz/public/lib/schemas.

For in tree development new, public contracts (schemas & codecs) should be added to this location unless there is a strong case for the contracts to be tied to an app or vendor. Centralizing the definition of these contracts this way helps prevent duplication and divergent implementations.

Entity Codecs

Topaz‘s schema Dart library exposes codecs that can be instantiated and used with Entity interactions enabled via the ModuleDriver. If a Module or Agent written in Dart needs to read or write Entity data it should use the codec for the correct type to ensure compatibility between components. When reading an Entity’s content, codecs expose structured data wrapped in an instance of an EntityData class holding primitive Dart types, e.g. String, int, List<String>, etc.

Vendor Specific Schemas

Contracts for structured data that is not expected to be exposed as a system level, public type but still needs to be shared should be added to the project's code as a package:

  • Public contracts: <layer>/app/<project>/public/lib/schemas/<lang>
  • Private contracts: <layer>/app/<project>/lib/schemas/<lang>

Type keys (URLs, reverse-DNS strings, mime, etc.) MUST be unique and should obviously belong to the vendor:

Adding New Entity Schemas

Tips for adding new schemas:

  • New schemas should be added to //topaz/public/lib/schemas or the appropriate location as described above.
  • Exports for Dart packages should have the type key in their path, e.g. this import should pull in all the necessary classes for schemas, codecs, and data import 'package:lib.schemas/com.fuchsia.color.dart'.
  • Avoid adding any new dependencies.
  • Try to only use primitive types within structured data.
  • Avoid language specific constructs within structured data.
  • Codecs should use corresponding schemas for validation during encoding and decoding.