Skip to content

Commit aa51353

Browse files
clokeprichvdhturt2liveerikjohnstonKitsuneRal
authored
MSC3856: Threads List API (#3856)
* Initial MSC3856 draft. * s/filter/include/g * Fix typo. Co-authored-by: Richard van der Hoff <[email protected]> * Add link to the current spec. Co-authored-by: Richard van der Hoff <[email protected]> * Link to MSC3440 for related_by_rel_types. * Rework and clarify intro. * Clarify what is returned by the API. * Add a note on dir. * Add info on ignored users. * Clarifications from review. Co-authored-by: Travis Ralston <[email protected]> * Add notes about MSC2836. * Add a comma to enum values. Co-authored-by: Erik Johnston <[email protected]> * Simplify pagination. * Fix typos. Co-authored-by: Alexey Rusakov <[email protected]> Co-authored-by: Richard van der Hoff <[email protected]> Co-authored-by: Travis Ralston <[email protected]> Co-authored-by: Erik Johnston <[email protected]> Co-authored-by: Alexey Rusakov <[email protected]>
1 parent 3b43d87 commit aa51353

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed

Diff for: proposals/3856-threads-list-api.md

+187
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
# MSC3856: Threads List API
2+
3+
An endpoint specific to listing the threads in a room is proposed to solve two
4+
client problems:
5+
6+
1. Clients wish to display threads ordered by the most recently active.
7+
2. Clients wish to display a list of threads the user has participated in.
8+
9+
It is currently difficult for clients to sort threads by the most recently
10+
responded to. Clients can use the [`/messages`](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv3roomsroomidmessages)
11+
API with a filter of `"related_by_rel_types": ["m.thread"]` (as defined in
12+
[MSC3440](https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/3440-threading-via-relations.md#fetch-all-threads-in-a-room))
13+
to fetch the list of threads in a room. This returns the root thread events in
14+
topological order of those events (either forwards or backwards depending on the
15+
`dir` parameter).
16+
17+
Each event also includes bundled aggregation, which will include the latest
18+
event in each thread.
19+
20+
In order to sort threads by the latest event in that thread clients must
21+
paginate through all of the threads in the room, inspect the latest event from
22+
the bundled aggregations and attempt to sort them. This can require many round
23+
trips to the server and is wasteful for both the client and server.
24+
25+
Unfortunately even when a client has all the threads in a room it is not able to accurately
26+
sort the threads since the client lacks the proper topological ordering of events. (The
27+
closest available information is the `age` or `origin_server_ts` of the events, but this
28+
is not always correct.)
29+
30+
Additionally, it is currently not possible for a client to query for threads that
31+
the user has participated in, as defined in
32+
[MSC3440](https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/3440-threading-via-relations.md#event-format):
33+
34+
> The user has participated if:
35+
>
36+
> * They created the current event.
37+
> * They created an event with a m.thread relation targeting the current event.
38+
39+
Currently, clients add the requesting user's MXID to the `related_by_senders` filter
40+
(as defined in
41+
[MSC3440](https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/3440-threading-via-relations.md#fetch-all-threads-in-a-room)),
42+
e.g. `"related_by_senders":["@alice:example.com"]`, but this results in missing
43+
threads where the user sent the root message and has not yet replied.
44+
45+
## Proposal
46+
47+
### Client-Server endpoint
48+
49+
A new endpoint is proposed to query for threads in a room. This endpoint requires
50+
authentication and is subject to rate-limiting.
51+
52+
The endpoint returns events, which represent thread roots and includes
53+
[bundled aggregations](https://spec.matrix.org/v1.3/client-server-api/#aggregations)
54+
in the response (which includes the "latest event" of each thread, see
55+
[MSC3440](https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/3440-threading-via-relations.md#event-format)
56+
for the format of bundled aggregations of threads).
57+
58+
The returned events are ordered by the latest event of each thread.
59+
60+
#### Request format
61+
62+
```
63+
GET /_matrix/client/v1/rooms/{roomId}/threads
64+
```
65+
66+
Query Parameters:
67+
68+
* **`include`**: `enum`
69+
70+
Whether to include all thread roots in the room or only thread roots which the
71+
user has participated in, meaning that the user has created the root event of
72+
the thread or replied to the thread (they have created an event with a `m.thread`
73+
relation targeting the root event).
74+
75+
One of `[all, participated]`. Defaults to `all`.
76+
* **`from`**: `string`
77+
78+
The token to start returning events from. This token can be obtained from an
79+
`next_batch` token returned by a previous request to this endpoint.
80+
81+
If it is not provided, the homeserver shall return a list of thread roots starting
82+
from the most recent visible event in the room history for the requesting user.
83+
* **`limit`**: Optional: a client-defined limit to the maximum
84+
number of threads to return per page. Must be an integer greater than zero.
85+
86+
Server implementations should impose a maximum value to avoid resource
87+
exhaustion.
88+
89+
#### Response format
90+
91+
* **`chunk`**: [`[ClientEvent]`](https://spec.matrix.org/v1.3/client-server-api/#room-event-format) **Required**
92+
93+
A list of room of events which are the root event of threads. Each event includes
94+
bundled aggregations. The order is chronological by the latest event in that thread.
95+
* **`next_batch`**: `string`
96+
97+
A token which can be passed back to this endpoint to request additional events.
98+
99+
If no further events are available (either because we have reached the start
100+
of the timeline, or because the user does not have permission to see any more
101+
events), this property is omitted from the response.
102+
103+
If the sender of an event is ignored by the current user the results are modified
104+
slightly. This has two situations:
105+
106+
1. If the ignored user sent the root thread event: the server should return the
107+
redacted form of the root event, but otherwise act as normal. This matches the
108+
information that a client would have if the threads list was aggregated locally
109+
(and generally matches the behavior if a thread root is unavailable, e.g. due
110+
to room history visibility).
111+
2. If the ignored user sent the latest thread event: the server should treat the
112+
latest event as not existing and replace it with the latest event from a
113+
non-ignored user; with the caveat that the ordering of the threads is not
114+
re-arranged due to this replacement.
115+
116+
#### Example request:
117+
118+
```
119+
GET /_matrix/client/v1/rooms/%21ol19s%3Ableecker.street/threads?
120+
limit=25&
121+
include=participated
122+
```
123+
124+
#### Example response:
125+
126+
```json
127+
{
128+
"chunk": [ClientEvent],
129+
"next_batch": "..."
130+
}
131+
```
132+
133+
### MSC3440 Filtering
134+
135+
This MSC replaces the [event filters added in MSC3440](https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/3440-threading-via-relations.md#fetch-all-threads-in-a-room)
136+
(`related_by_rel_types` and `related_by_senders`) as the only known use-case is
137+
more efficiently solved by this MSC.
138+
139+
## Potential issues
140+
141+
None foreseen.
142+
143+
## Alternatives
144+
145+
### Reusing the `/messages` endpoint
146+
147+
Additional parameters could be added to the `/messages` endpoint to control the
148+
ordering of the returned results. This would likely not be compatible with all
149+
the other options available on that endpoint.
150+
151+
Keeping this a separate endpoint also gives the possibility of additional
152+
threads-specific filtering in the future.
153+
154+
### MSC2836 Threading
155+
156+
[MSC2836](https://github.com/matrix-org/matrix-spec-proposals/pull/2836) includes
157+
a generic `/event_relationships` endpoint, but it is overly complex for
158+
[MSC3440](https://github.com/matrix-org/matrix-doc/pull/3440)-style threads.
159+
160+
MSC2836 attempts to solve a larger problem, including allowing for arbitrary
161+
branching of threads (and many levels of event relations). MSC3440 forbids creating
162+
threads off a threaded message, allowing for a simpler design. Additionally, the
163+
MSC2836 design is more computationally intensive for both clients and servers to
164+
implement due to the tree-like nature of the query.
165+
166+
A benefit to the MSC2836 design is that it supports querying over federation for
167+
additional events related to the event in question.
168+
169+
## Security considerations
170+
171+
As with other endpoints that accept a `limit`, homeservers should apply a hard
172+
server-side maximum.
173+
174+
## Future extensions
175+
176+
It does not seem useful to be able to paginate in reverse order, i.e. starting with
177+
the thread which was least recently updated. If there becomes a future need of this
178+
a `dir` parameter could be added which takes an enum value of `[f, b]` defaulting to
179+
`b` to maintain backwards compatibility with this proposal.
180+
181+
## Unstable prefix
182+
183+
The client-server API will be: `/_matrix/client/unstable/org.matrix.msc3856/rooms/{roomId}/threads`
184+
185+
## Dependencies
186+
187+
N/A

0 commit comments

Comments
 (0)