mirror of
https://github.com/matrix-org/matrix-spec
synced 2026-03-28 14:04:10 +01:00
Clarify using parent/child language
This commit is contained in:
parent
0d35037f14
commit
532b06b25d
|
|
@ -1849,47 +1849,58 @@ In some cases it is desirable to logically associate one event's contents with
|
||||||
another event's contents. For example, when replying to a message, editing an
|
another event's contents. For example, when replying to a message, editing an
|
||||||
event, or simply looking to add context for an event's purpose.
|
event, or simply looking to add context for an event's purpose.
|
||||||
|
|
||||||
Relationships are defined as part of an event's `content`. Any event can relate
|
Events are related to each other in a parent/child structure, where any event can
|
||||||
to any other event, however the relationship itself might have restrictions
|
become a parent by simply having a child event point at it. Parent events do not
|
||||||
depending on its `rel_type`. Those restrictions are described by the relationship
|
define their children, instead relying on the children to describe their parent.
|
||||||
type in this specification, if any exist.
|
|
||||||
|
|
||||||
The relationship is stored under the `m.relates_to` key of `content`, referencing
|
The relationship between a child and it's parent event is described in the child
|
||||||
the "parent" event. Both the event with `m.relates_to` and the event targeted by
|
event's `content` as `m.relates_to` (defined below). A child event can point at
|
||||||
`m.relates_to` MUST exist in the same room.
|
any other event, including another child event, to build the relationship so long
|
||||||
|
as both events are in the same room, however additional restrictions might be imposed
|
||||||
|
by the `rel_type` itself.
|
||||||
|
|
||||||
{{% boxes/note %}}
|
{{% boxes/note %}}
|
||||||
For simplicity, a single type of relationship is permitted on an event at a time.
|
Child events can point at other child events, forming a chain of events. These chains
|
||||||
A future MSC might change this if a use case arises.
|
can naturally take the shape of a tree if two independent children point at a single
|
||||||
|
parent event, for example.
|
||||||
{{% /boxes/note %}}
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
{{% boxes/note %}}
|
To allow the server to aggregate and find child events for a parent, the `m.relates_to`
|
||||||
An event with `m.relates_to` can relate to another event with `m.relates_to`,
|
key of an event MUST be included in the plaintext copy of the event. It cannot be
|
||||||
forming a sort of chain of events.
|
exclusively recorded in the encrypted payload as the server cannot decrypt the event
|
||||||
{{% /boxes/note %}}
|
for processing.
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
To allow the server to aggregate and find relations on events, the `m.relates_to`
|
|
||||||
key of an event must be included in the plaintext copy of the event. It cannot
|
|
||||||
be exclusively recorded in the encrypted payload of an event.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
{{% boxes/warning %}}
|
{{% boxes/warning %}}
|
||||||
If an encrypted event contains an `m.relates_to` in its payload, it should be
|
If an encrypted event contains an `m.relates_to` in its payload, it should be
|
||||||
ignored and instead favour the plaintext `m.relates_to` copy (including when there
|
ignored and instead favour the plaintext `m.relates_to` copy (including when there
|
||||||
is no plaintext copy).
|
is no plaintext copy). This is to ensure the client's behaviour matches the server's
|
||||||
|
capability to handle relationships.
|
||||||
{{% /boxes/warning %}}
|
{{% /boxes/warning %}}
|
||||||
|
|
||||||
|
Improperly formed or structured relationships are simply ignored. For example, the
|
||||||
|
child and parent events being in different rooms or the relationship missing fields
|
||||||
|
required by the schema below. The events would appear independent of each other or
|
||||||
|
optionally with an error message (if rendered/handled by the client exclusively).
|
||||||
|
|
||||||
`m.relates_to` is described as follows:
|
`m.relates_to` is described as follows:
|
||||||
|
|
||||||
{{% definition path="api/client-server/definitions/m.relates_to" %}}
|
{{% definition path="api/client-server/definitions/m.relates_to" %}}
|
||||||
|
|
||||||
#### Relationship types
|
#### Relationship types
|
||||||
|
|
||||||
|
{{% boxes/note %}}
|
||||||
|
While this specification describes an `m.relates_to` object containing a `rel_type`, there
|
||||||
|
is not currently any relationship type which uses this structure. Replies, described below,
|
||||||
|
form their relationship outside of the `rel_type` in order to allow other, future, relationship
|
||||||
|
types to make use of replies in addition to their normal behaviour.
|
||||||
|
|
||||||
|
Custom `rel_type`s can, and should, still use the schema described above for relevant
|
||||||
|
behaviour.
|
||||||
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
This specification describes the following relationship types:
|
This specification describes the following relationship types:
|
||||||
|
|
||||||
* [Rich replies](#rich-replies) (**Note**: uses a different relations structure than
|
* [Rich replies](#rich-replies) (**Note**: does not use `rel_type`).
|
||||||
described here)
|
|
||||||
|
|
||||||
{{% boxes/note %}}
|
{{% boxes/note %}}
|
||||||
This specification does not currently define any relation type which requires
|
This specification does not currently define any relation type which requires
|
||||||
|
|
@ -1904,17 +1915,18 @@ or aggregation of related events.
|
||||||
|
|
||||||
{{% added-in v="1.3" %}}
|
{{% added-in v="1.3" %}}
|
||||||
|
|
||||||
Some events are "aggregated" by the server depending on their relationships.
|
Some child events can be "aggregated" or "bundled" by the server, depending on their
|
||||||
This can allow a set of related events to be summarised.
|
`rel_type`. This can allow a set of child events to be summarised to the client without
|
||||||
|
the client needing the child events themselves.
|
||||||
|
|
||||||
For example, a relationship might define an extra `key` field which, when used with
|
An example of this might be that a `rel_type` requires an extra `key` field which, when
|
||||||
the appropriate `rel_type`, would mean that the client receives a total count for
|
appropriately specified, would mean that the client receives a total count for the number
|
||||||
the number of times that `key` was used in a relationship.
|
of times that `key` was used by child events.
|
||||||
|
|
||||||
The actual aggregation format depends on the relationship type.
|
The actual aggregation format depends on the `rel_type`.
|
||||||
|
|
||||||
{{% boxes/note %}}
|
{{% boxes/note %}}
|
||||||
This specification does not currently describe any relation types which require
|
This specification does not currently describe any `rel_type` which require
|
||||||
aggregation, however [namespaced](/appendices#identifier-grammar) relationship
|
aggregation, however [namespaced](/appendices#identifier-grammar) relationship
|
||||||
types might have aggregation behaviour.
|
types might have aggregation behaviour.
|
||||||
{{% /boxes/note %}}
|
{{% /boxes/note %}}
|
||||||
|
|
@ -1922,9 +1934,10 @@ types might have aggregation behaviour.
|
||||||
When aggregations are summarised on an event, it is known as a "bundled aggregation"
|
When aggregations are summarised on an event, it is known as a "bundled aggregation"
|
||||||
or "bundle" for simplicity. The act of doing this is "bundling".
|
or "bundle" for simplicity. The act of doing this is "bundling".
|
||||||
|
|
||||||
The bundle for an event is found under the `unsigned` field of the event, when that
|
When an event is served to the client through the APIs listed below, a `m.relations` field
|
||||||
event is served to the client through the APIs listed below. The field, `m.relations`,
|
is included under `unsigned` if the event has child events which point at it. The `m.relations`
|
||||||
is an object with a key of the relationship type and value being the bundle itself.
|
field is an object keyed by `rel_type` and value being the type-specific format for that
|
||||||
|
`rel_type`, also known as the bundle.
|
||||||
|
|
||||||
For example (unimportant fields not included):
|
For example (unimportant fields not included):
|
||||||
|
|
||||||
|
|
@ -1963,7 +1976,7 @@ For example (unimportant fields not included):
|
||||||
Note how the `org.example.possible_annotations` bundle is an array compared to the
|
Note how the `org.example.possible_annotations` bundle is an array compared to the
|
||||||
`org.example.possible_thread` bundle where the server is summarising the state of
|
`org.example.possible_thread` bundle where the server is summarising the state of
|
||||||
the relationship in a single object. Both are valid bundles, and their exact types
|
the relationship in a single object. Both are valid bundles, and their exact types
|
||||||
depend on the relationship type.
|
depend on the `rel_type`.
|
||||||
|
|
||||||
The endpoints where the server *should* include the `m.relations` unsigned field are:
|
The endpoints where the server *should* include the `m.relations` unsigned field are:
|
||||||
|
|
||||||
|
|
@ -1983,7 +1996,7 @@ such as `/initialSync`.
|
||||||
While this functionality allows the client to see what was known to the server at the
|
While this functionality allows the client to see what was known to the server at the
|
||||||
time of handling, the client should continue to aggregate locally if it is aware of
|
time of handling, the client should continue to aggregate locally if it is aware of
|
||||||
the relationship type's behaviour. For example, a client might increment a `count`
|
the relationship type's behaviour. For example, a client might increment a `count`
|
||||||
on a related event's bundle if it saw a new event which referenced that event.
|
on a parent event's bundle if it saw a new child event which referenced that parent.
|
||||||
|
|
||||||
{{% boxes/warning %}}
|
{{% boxes/warning %}}
|
||||||
The bundle provided by the server only includes events which were known at the time
|
The bundle provided by the server only includes events which were known at the time
|
||||||
|
|
@ -1996,27 +2009,26 @@ its own, as the server will not have considered them.
|
||||||
{{% boxes/note %}}
|
{{% boxes/note %}}
|
||||||
Events from [ignored users](#ignoring-users) do not appear in the bundle or aggregation
|
Events from [ignored users](#ignoring-users) do not appear in the bundle or aggregation
|
||||||
from the server, however clients might still have events from ignored users cached. Like
|
from the server, however clients might still have events from ignored users cached. Like
|
||||||
with normal events, clients will need to de-aggregate events sent by ignored users to
|
with normal events, clients will need to de-aggregate child events sent by ignored users to
|
||||||
avoid them being considered in counts. Servers must additionally ensure they do not
|
avoid them being considered in counts. Servers must additionally ensure they do not
|
||||||
consider events from ignored users when preparing a bundle for the client.
|
consider child events from ignored users when preparing a bundle for the client.
|
||||||
{{% /boxes/note %}}
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
When a parent event is redacted, the events which pointed to that parent remain, however
|
When a parent event is redacted, the child events which pointed to that parent remain, however
|
||||||
when an event which points at a parent is redacted then the relationship is broken.
|
when a child event is redacted then the relationship is broken. Therefore, the server needs
|
||||||
Therefore, the server needs to de-aggregate or disassociate the event once the relationship
|
to de-aggregate or disassociate the event once the relationship is lost. Clients with local
|
||||||
is lost. Clients with local aggregation or which handle redactions locally should do the
|
aggregation or which handle redactions locally should do the same.
|
||||||
same.
|
|
||||||
|
|
||||||
It is suggested that clients perform local echo on aggregations. For instance, aggregating
|
It is suggested that clients perform local echo on aggregations. For instance, aggregating
|
||||||
the event into a bundle optimistically until the server returns a failure or the client
|
a new child event into a bundle optimistically until the server returns a failure or the client
|
||||||
gives up on sending the event, at which point the event should be de-aggregated and an
|
gives up on sending the event, at which point the event should be de-aggregated and an
|
||||||
error or similar shown. The client should be cautious to not aggregate an event twice if
|
error or similar shown. The client should be cautious to not aggregate an event twice if
|
||||||
it has already optimistically aggregated the event. Clients are encouraged to take this
|
it has already optimistically aggregated the event. Clients are encouraged to take this
|
||||||
a step further to additionally track related events which target unsent/pending events,
|
a step further to additionally track child events which target unsent/pending events,
|
||||||
likely using the transaction ID as a temporary event ID until a proper event ID is known.
|
likely using the transaction ID as a temporary event ID until a proper event ID is known.
|
||||||
|
|
||||||
{{% boxes/warning %}}
|
{{% boxes/warning %}}
|
||||||
Due to history visibility restrictions, related events might not be visible to the user
|
Due to history visibility restrictions, child events might not be visible to the user
|
||||||
if they are in a section of history the user cannot see. This can mean inaccurate bundles
|
if they are in a section of history the user cannot see. This can mean inaccurate bundles
|
||||||
for events that are "out of range".
|
for events that are "out of range".
|
||||||
|
|
||||||
|
|
@ -2024,14 +2036,20 @@ Additionally, if the server is missing portions of the room history then it may
|
||||||
able to accurately aggregate the events.
|
able to accurately aggregate the events.
|
||||||
{{% /boxes/warning %}}
|
{{% /boxes/warning %}}
|
||||||
|
|
||||||
#### API
|
#### Relationships API
|
||||||
|
|
||||||
To retrieve relations for an event from the server, the client can call the following
|
To retrieve the child events for a parent from the server, the client can call the
|
||||||
endpoint with relevant information. The endpoint does not aggregate the events and is
|
following endpoint with relevant inforamtion. This endpoint does not aggregate the child
|
||||||
instead paginated: clients can perform local aggregation if needed.
|
events and is instead paginated: clients can perform local aggregation if needed. This
|
||||||
|
allows clients to retrieve child events which do not require aggregation but still make
|
||||||
|
use of `rel_type`.
|
||||||
|
|
||||||
This endpoint is particularly useful if the client has lost context on the bundle for
|
This endpoint is particularly useful if the client has lost context on the bundle for
|
||||||
an event and needs to rebuild/verify it.
|
a parent event and needs to rebuild/verify it.
|
||||||
|
|
||||||
|
{{% boxes/note %}}
|
||||||
|
Because replies do not use `rel_type`, they will not be accessible via this API.
|
||||||
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
{{% http-api spec="client-server" api="relations" %}}
|
{{% http-api spec="client-server" api="relations" %}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@
|
||||||
type: object
|
type: object
|
||||||
title: m.relates_to
|
title: m.relates_to
|
||||||
description: |-
|
description: |-
|
||||||
A description of a valid `m.relates_to` definition on an event. This is contained
|
A description of a valid `m.relates_to` definition on a child event. This is contained
|
||||||
within the event's `content` alongside other fields for that event type.
|
within the event's `content` alongside other fields for the relevant event type.
|
||||||
example: {
|
example: {
|
||||||
# We deliberately "break" the example by including the top-level field so it renders
|
# We deliberately "break" the example by including the top-level field so it renders
|
||||||
# sensibly for readers of the spec.
|
# sensibly for readers of the spec.
|
||||||
|
|
@ -35,9 +35,9 @@ properties:
|
||||||
The relationship type determines how clients should perceive the event, and in what
|
The relationship type determines how clients should perceive the event, and in what
|
||||||
context. Some relationship types are processed server-side for "bundling", though not
|
context. Some relationship types are processed server-side for "bundling", though not
|
||||||
all relationships require such behaviour. For example, an `m.thread` relationship type
|
all relationships require such behaviour. For example, an `m.thread` relationship type
|
||||||
denotes that the event is part of a "thread" of messages and should be rendered as
|
might denote that the event is part of a "thread" of messages and should be rendered as
|
||||||
such.
|
such.
|
||||||
event_id:
|
event_id:
|
||||||
type: string
|
type: string
|
||||||
description: The event ID in the same room this event relates to.
|
description: The parent event ID in the same room this event points/relates to.
|
||||||
required: ['rel_type', 'event_id']
|
required: ['rel_type', 'event_id']
|
||||||
|
|
|
||||||
|
|
@ -29,16 +29,19 @@ securityDefinitions:
|
||||||
paths:
|
paths:
|
||||||
"/rooms/{roomId}/relations/{eventId}/{relType}/{eventType}":
|
"/rooms/{roomId}/relations/{eventId}/{relType}/{eventType}":
|
||||||
get:
|
get:
|
||||||
summary: Get the related events for a given event, with optional filter.
|
summary: Get the cgukd events for a given parent event, with optional filter.
|
||||||
description: |-
|
description: |-
|
||||||
Retrieve all of the related events for a given event, optionally filtering
|
Retrieve all of the chikd events for a given parent event, optionally filtering
|
||||||
down by relationship type and related event type.
|
down by relationship type and related event type.
|
||||||
|
|
||||||
Note that while this endpoint indicates `relType` and `eventType` being
|
Note that while this endpoint indicates `relType` and `eventType` being
|
||||||
required, they can be individually omitted to retrieve all matching events.
|
required, they can be individually omitted to retrieve all matching events.
|
||||||
When omitting the path parameters, a trailing slash must not be included
|
When omitting the path parameters, a trailing slash must not be included
|
||||||
(otherwise the search will be for an empty string).
|
(otherwise the search will be for an empty string).
|
||||||
operationId: getEventsRelatingToEvent
|
|
||||||
|
When combining the use of `relType` and `eventType`, the server will return
|
||||||
|
child events which match *both* conditions rather than *either*.
|
||||||
|
operationId: getChildEventsForParentEvent
|
||||||
security:
|
security:
|
||||||
- accessToken: []
|
- accessToken: []
|
||||||
parameters:
|
parameters:
|
||||||
|
|
@ -59,7 +62,7 @@ paths:
|
||||||
name: relType
|
name: relType
|
||||||
description: |-
|
description: |-
|
||||||
The [relationship type](/client-server-api/#relationship-types) to search
|
The [relationship type](/client-server-api/#relationship-types) to search
|
||||||
for, if any. Exclude to find all events which relate to the supposed parent
|
for, if any. Exclude to find all child events which point to the supposed parent
|
||||||
event with any `rel_type`.
|
event with any `rel_type`.
|
||||||
required: true # we can't say false, annoyingly
|
required: true # we can't say false, annoyingly
|
||||||
x-example: "org.example.my_relation"
|
x-example: "org.example.my_relation"
|
||||||
|
|
@ -67,8 +70,8 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
name: eventType
|
name: eventType
|
||||||
description: |-
|
description: |-
|
||||||
The event type of related events to search for, if any. Exclude to find all
|
The event type of child events to search for, if any. Exclude to find all
|
||||||
events of any type which relate to the supposed parent event.
|
child events of any type which point to the supposed parent event.
|
||||||
|
|
||||||
Note that in encrypted rooms this will typically always be `m.room.encrypted`
|
Note that in encrypted rooms this will typically always be `m.room.encrypted`
|
||||||
regardless of the event type contained within the encrypted payload.
|
regardless of the event type contained within the encrypted payload.
|
||||||
|
|
@ -114,8 +117,8 @@ paths:
|
||||||
|
|
||||||
200:
|
200:
|
||||||
description: |-
|
description: |-
|
||||||
The paginated events which relate to the supposed parent. If no events are
|
The paginated child events which point to the supposed parent. If no events are
|
||||||
related to the parent, an empty `chunk` is returned.
|
pointing to the parent, an empty `chunk` is returned.
|
||||||
examples:
|
examples:
|
||||||
application/json: {
|
application/json: {
|
||||||
"chunk": [{
|
"chunk": [{
|
||||||
|
|
@ -135,10 +138,10 @@ paths:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
chunk:
|
chunk:
|
||||||
title: "RelatedEventsChunk"
|
title: "ChildEventsChunk"
|
||||||
type: array
|
type: array
|
||||||
description: |-
|
description: |-
|
||||||
The events which relate to the parent event, after applicable filters.
|
The child events which point to the parent event, after applicable filters.
|
||||||
items:
|
items:
|
||||||
allOf:
|
allOf:
|
||||||
- "$ref": "definitions/client_event.yaml"
|
- "$ref": "definitions/client_event.yaml"
|
||||||
|
|
@ -153,7 +156,9 @@ paths:
|
||||||
An opaque string representing a pagination token. The absence of this token
|
An opaque string representing a pagination token. The absence of this token
|
||||||
means there are no prior results to fetch, i.e. this is the first batch.
|
means there are no prior results to fetch, i.e. this is the first batch.
|
||||||
404:
|
404:
|
||||||
description: The supposed parent event was not found or you do not have permission to read this event.
|
description: |-
|
||||||
|
The supposed parent event was not found or the user does not have permission to read
|
||||||
|
this event (it might be contained in history that is not accessible to the user).
|
||||||
examples:
|
examples:
|
||||||
application/json: {
|
application/json: {
|
||||||
"errcode": "M_NOT_FOUND",
|
"errcode": "M_NOT_FOUND",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue