blob: c668578b27d1a3e62910653b2d7f00ab2a4fe929 [file] [log] [blame] [view]
# 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:
* reverse-DNS (preferred): 'com.vendor.special-type'
* URL: 'https://api.vendor.com/special-type'
* mime: 'application/x-special-type+json'
## 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.