This has to be in order of dependencies, so reverse import order. For example, for the connectors/demo's demo_data.proto which has an import "google/protobuf/timestamp.proto" this has to FIRST contain the Timestamp's and THEN the Something's FileDescriptorProto.
This is the API which Enola Connectors implement.
Enola Core calls this API for each of the listed connector of an EntityKind.
Enola clients (such as a CLI or UI) use the EnolaService, instead of this
directly. This is the gRPC equivalent of the internal EntityAspect Java API.
Related Enola Entities. Intended for consumption by both machines as well as humans. Key is EntityKind#related.key (modeled by EntityRelationship), value is ID.
URIs linked to this entity providing additional information about it on other systems.
Key is EntityKind#link.key, value is an URI, often pointing to "back-end" state information, used e.g. to determine an Entity's status, etc.
If http[s]: then these are informational and destined to be displayed to a human on a UI, but not "machine readable" for interpretation. Any other URI scheme is intended to be (only) machine readable and up to the client to interpret. This URI may well be specific to the respective schema connector.
These can be requested to be "inlined" in responses. |
| data | Entity.DataEntry | repeated | Data about the Entity, in machine readable form. Key is EntityKind#data.key, value is an Any protobuf. |
ID of an Entity known to Enola, fully qualified.
Can be formatted to and parsed from several different string text forms,
see Java class dev.enola.core.IDs.java
Namespace. Serves to distinguish same entity names (below). This is optional if in your use of Enola you avoid name conflicts. It's like in C# or "package" in Java or Go or the xmlns: from XML Schema, or whatever the hell confusing thing ;) that Python is doing about this. Validated to only contain [a-z0-9_.] characters, so it's safe in URLs. By convention can contain '.' for sub-namespacing, but does not have to. The namespace of an Entity is always the same as its EntityKind.
Entity Kind Name. This is mandatory and thus always present. This refers to an EntityKind and not an individual Entity, despite the name. (In practice this is just shorter and clearer for people to understand.) Validated to only contain [a-z0-9_] characters, so it's safe in URLs.
Path. This is mandatory and thus always present with at least 1 element. Think of this as what would typically uniquely identify this entity IRL; e.g. a "hostname" or some UUID or a S/N or whatever is its "primary key". Validated to only contain [a-z0-9_-.] characters, so it's safe in URLs. (This restriction could in theory be relaxed, if there was a strong need to support it; as long as sufficient test coverage is added for correct encoding in URIs, see https://en.m.wikipedia.org/wiki/URL_encoding.) Multiple "segments" are supported for "composed keys", for example a network/context/namespace/name kind of ID.
Request for a list of entities.
For the https://docs.enola.dev/use/library/ example model, examples could be:
A. Set 'kind' to 'book_kind', without the 'isbn' path - list all
B. Set 'kind' to 'book', and the 'library' path - from a specific library
Note that for the example library model you would not use the related_filter,
as the only two related (the 'library' and the 'kind') are available in the
paths; but if it had any other related, one could filter one or several of
those.
Filters on related entities. The key is as in EntityKind or Entity's .related, and the value is the ("scope") related entity to filter on. If there is more than one, these are AND, not OR.
Invokes remote connector via gRPC. The "connection string" here is a target endpoint in hostname:port format. (It's NOT an URI, so there is no scheme:// nor any /path/ or #fragment.)
ID. The ns may be filled in by the reader, if omitted in *-model.textproto. The entity is the name of THIS EntityKind! This is typically never changed anymore after initial creation. The path contains' the segments' names (here, whereas in Entity it's the "values").
ID reference to another Entity. This ID's ns/entity/paths fields can contain a template, like Link#uri_template. Alternatively, this can be left empty, and set by connectors.
URI template, to create URL. As an ID URI Template (RFC 6570); see https://en.wikipedia.org/wiki/URI_Template. The available variables are the ID's path parameters, as well as a special proto.* which allows to declaratively create links out of the Any proto (instead of coding link generation in the service; which is always still also possible).
Link to something related. Intended both for human consumption in a UI, as well as machine readable linked data relationships. Typically a Template of an (HTML a/href-like) HTTP URL, or enola: URI. Template parameters refer to other properties of the Type.
Human readable label of this property, may be several words, any case. This is a map where the key is an IETF BCP 47 "language code" (like "en" or "de-CH") and the value is text in that language. These can easily be changed at any time without breaking anything in Enola.
Documentation description (as URL; either absolute, or URL relative to the model's location - from where a UI will serve it). TODO Is this a [(dev.enola.type) = "enola.dev/url"]? Really??
Unique ID of this Type.
For example, "d19974d6-0695-458d-bdd4-3ad89578db92".
This "provides a relatively short yet unambiguous way to refer to a type",
as "fully-qualified type names may be large and waste space when
transmitted on the wire", and it "lets programmers change the symbolic name
while keeping a fixed ID" (inspired by
https://capnproto.org/language.html#unique-ids).
It's recommended that this is set by the human author of the Type,
but if it's not, it will be automatically generated by hashing the name.
(This defeats the purpose of a "permanent" ID - but it's at least possible
to set it later, if a name is ever changed.)
TODO "Nicely render" this in the Web UI, using dev.enola.core.ByteSeq.
TODO Do we really this, actually?
bytes id = 1 [(dev.enola.type) = "enola.dev/id"];
Short technical name of this Type. Must be unique within the environment this Enola instance operates. Publicly, using something that looks like an IRI/URI/URL is a simple way for uniqueness. For example, "your.org/something" (which is technically a relative URI, by chance). This string is NOT (necessarily) a valid URL; e.g. you (generally) cannot "http GET your.org/something". As a convenience for humans which type this into their web browser, your.org MAY set up a "redirector" which responds with a 30x to somewhere "interesting" for a human (not a machine), but that's just "nice", nothing more. Enola will never use it as anything else than simply a unique string.
URI Template of instances of this Type. For example, "hello/{message}" - where the parameter "message" refers to a property; so instances would be e.g. "hello/world" and "hello/planets". TODO Rename Type.uri to iri_template! (Because that's what this really is.)
Human readable label of this type, may be several words, any case. This is a map where the key is an IETF BCP 47 "language code" (like "en" or "de-CH") and the value is text in that language. These can easily be changed at any time without breaking anything in Enola.
Documentation description (as URL; either absolute, or URL relative to the model's location - from where a UI will serve it). TODO Is this a [(dev.enola.type) = "enola.dev/url"]? Really??
EntityKind. This is from the original Enola design, and may later be removed. TODO Should this really be embedded? Really? Probably better an ID as reference? Good test! string entity_kind = 10 [(dev.enola.type) = "enola.dev/EntityKind"];