xRegistry Events 🔗

Abstract 🔗

This specification defines the events that an xRegistry server MAY generate.

Table of Contents 🔗

Overview 🔗

As updates are made to entities within an xRegistry instance, events SHOULD be generated to notify interested parties of those changes. This specification defines the metadata associated with each event as [CloudEvent][https://cloudevents.io) context attributes. Whether CloudEvents are used in the generation/serialization of the events is OPTIONAL, but it is RECOMMENDED.

This specification does not mandate the mechanisms by which events are sent to consumers, nor does it mandate how consumers register interest in receiving events.

Below is a sample event serialized as a "structured" JSON CloudEvent due to a Group's name being changed:

{
  "specversion": "1.0",
  "type": "io.xregistry.group.updated",
  "source": "https://example.com",
  "subject": "/dirs/d1",
  "id": "A234-1234-1234",
  "time": "2025-09-01T12:01:02Z",
  "xregcorrelationid": "B9282-129301",
  "data": {
    "changed": [ "epoch", "modifiedat", "name" ]
  }
}

Notations and Terminology 🔗

Notational Conventions 🔗

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

In the pseudo JSON format snippets ? means the preceding item is OPTIONAL, * means the preceding item MAY appear zero or more times, and + means the preceding item MUST appear at least once. The presence of the # character means the remaining portion of the line is a comment. Whitespace characters in the JSON snippets are used for readability and are not normative.

Use of <...> the notation indicates a substitutable value where that is meant to be replaced with a runtime situational-specific value as defined by the word/phase in the angled brackets. For example <NAME> might be expected to be replaced by the "name" of the item being discussed.

Event Definition 🔗

Notification of changes to the entities within an xRegistry instance SHOULD be exposed as events. These changes could be the result of an end-user interaction with the Registry, or due to some other (possibly internal) processing of the Registry data.

A single interaction with the Registry MAY result in multiple events, however, within the scope of one interaction (see xregcorrelationid) the following constraints apply:

The following sections specify the metadata defined for xRegistry events. Implementations MAY define additional metadata.

CloudEvent type Core Context Attribute 🔗

The type of action taken on the entity. The value MUST be of the form: io.xregistry.<ENTITY>.<ACTION> where:

This context attribute MUST be present in each event.

CloudEvent source Core Context Attribute 🔗

The xRegistry in which the entity exists. The value MUST be an absolute URL to the root of the xRegistry instance.

This context attribute MUST be present in each event.

CloudEvent subject Core Context Attribute 🔗

The xid of the entity acted upon. While this attribute is OPTIONAL in the CloudEvents specification, it is REQUIRED to be present in an xRegistry event.

Note: constructing a URL by appending the subject value to the source value MUST result in an absolute URL to the entity (assuming any trailing / on source is removed since XIDs always start with /).

This context attribute MUST be present in each event.

CloudEvent time Core Context Attribute 🔗

The time of when the interaction occurred. This value MUST be the same for all events generated within the same interaction.

Its value MUST be an RFC3339 timestamp normalized to UTC. Use of a time-zone notation is RECOMMENDED. The value used SHOULD match the current date/time used by the Registry during the processing of the interaction. Typically, this will be the modifiedat value assigned to the entities being processed.

This context attribute is NOT REQUIRED to be present in the event, but is RECOMMENDED.

xregcorrelationid Extension Context Attribute 🔗

A value that uniquely identifies the interaction in which one or more events occurred. This value has the following constraints:

When an interaction has a request-response message exchange pattern, and xregcorrelationid values are included in resulting events, then the response message for the interaction MUST include this value. In the case of an HTTP interaction, the following HTTP header MUST be present in the response flow:

xRegistry-xregcorrelationid: <STRING>

This allows for clients to identify which events were generated as a result of each request-response operation.

This context attribute is NOT REQUIRED to be present in the event, but is RECOMMENDED.

CloudEvent data 🔗

When present, and serialized in JSON, the data MUST be of the form:

{
  "changed": [ "<STRING>", * ] ?
}

The changed attribute, when present, has the following constraints:

There are certain events where non-top-level attributes are included, and those will be noted in the Entity Events sections below. When they do appear they MUST use the JSONPath dot (.) notation to express the traversal to the attribute of interest.

If an entity is updated for multiple reasons during the processing of an interaction, per the rules previously stated, only one updated event will be generated. This means the attribute names of all impacted attributes MUST be merged into one changed list.

While changed is OPTIONAL, it is RECOMMENDED to be present on event where it is permitted due to its usefulness for consumers. However, if exposure of this information would be inappropriate for some scenarios then it MAY be excluded. For example, for privacy/security reasons.

While this specification only shows data being present when changed is permitted, implementations MAY define their own metadata to be included in the data of a CloudEvent.

This metadata (data) is NOT REQUIRED to be present in the event, but is RECOMMENDED.

Entity Events 🔗

This section defines which <ACTION> values are applicable for each <ENTITY> value.

registry Events 🔗

The io.xregistry.registry.created and io.xregistry.registry.updated events are not defined as part of this specification as those operations are not defined in the xRegistry specification. It is expected that the tooling that performs those operations will define those events, if needed.

model Events 🔗

Often io.xregistry.model.updated and io.xregistry.modelsource.updated will be generated at the same time since model updates are most likely done by changing the modelsource attribute. However, since the model might change for other reasons, users who are interested in all model changes need to watch for io.xregistry.model.update events, not io.xregistry.modelsource.updated events.

modelsource Events 🔗

Often io.xregistry.model.updated and io.xregistry.modelsource.updated will be generated at the same time since model updates are most likely done by changing the modelsource attribute. However, since the model might change for other reasons, users who are only interested in changes related to user modifications of the model need to watch for io.xregistry.modelsource.update events, not io.xregistry.model.updated events.

capabilities Events 🔗

group Events 🔗

resource Events 🔗

version Events 🔗

Sample xRegistry Interactions 🔗

In these examples, unless otherwise stated, assume that the Registry has the following model definition:

{
  "groups": {
    "dirs": {
      "singular": "dir",
      "resources": {
        "files": {
          "singular": "file"
        }
      }
    }
  }
}

Update a Registry attribute 🔗

Create a tree of entities 🔗

Update a Resource attribute (a default Version attribute) 🔗

Update a Resource's meta sub-object 🔗

Update a Resource's meta sub-object and deprecate the Resource 🔗

Import an entire Registry 🔗

Create a new Version - non-sticky 🔗

Create a new Version - sticky 🔗

Change defaultversionid pointer 🔗

Update a Version attribute (the default Version) 🔗

Update a Version attribute (not the default Version) 🔗

Create a new Version - not sticky 🔗

Create a new Version - sticky 🔗

Delete a Group 🔗

Creating a Group with complete client HTTP message exchange 🔗

Client Request:

PUT /dirs/d1
Host: example.com
Content-Type: application/json

{}

xRegistry Response:

HTTP/1.1 200 OK
Content-Type: application/json
Date: Wed, 02 Jul 2025 12:00:01 GMT
xRegistry-xregcorrelationid: B9282-129301

{
  "dirid": "d1",
  "self": "http://example.com/dirs/d1",
  "xid": "/dirs/d1",
  "epoch": 1,
  "createdat": "2025-07-02T12:00:01Z",
  "modifiedat": "2025-07-02T12:00:01Z",

  "filesurl": "http://example.com/dirs/d1/files",
  "filescount": 0
}

Events Generated:

{
  "specversion": "1.0",
  "type": "io.xregistry.registry.updated",
  "source": "https://example.com",
  "subject": "/",
  "id": "A234-1234-1234",
  "time": "2025-07-02T12:00:01Z",
  "xregcorrelationid": "B9282-129301",
  "data": {
    "changed": [ "dirs", "dirscount", "epoch", "modifiedat" ]
  }
}
{
  "specversion": "1.0",
  "type": "io.xregistry.group.created",
  "source": "https://example.com",
  "subject": "/dirs/d1",
  "id": "A432-4321-4321",
  "time": "2025-07-02T12:00:01Z",
  "xregcorrelationid": "B9282-129301"
}