Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSC1753: client-server capabilities API #1753

Merged
merged 7 commits into from
Jan 9, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions proposals/1753-capabilities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# MSC1753: client-server capabilities API

A mechanism is needed for clients to interrogate servers to establish whether
particular operations can be performed.

For example, users may not be able to change their password if a server is
configured to authenticate against a separate system, in which case it is
nonsensical to offer the user such an option.

## Proposal

### `POST /_matrix/client/r0/capabilities`
richvdh marked this conversation as resolved.
Show resolved Hide resolved

We will add a new endpoint to the client-server API: `POST
/_matrix/client/r0/capabilities`. The endpoint will be authenticated as normal
via an access token.

The body of the request will list the capabilities the client is interested
in, as shown:

```json
{
"capabilities": {
"m.capability_one": {},
"com.example.custom_capability": {}
}
}
```

The keys of the `capabilities` object are capability identifiers. As with
other identifiers in the Matrix protocol, the `m.` prefix is reserved for
definition in the Matrix specification; other values can be used within an
organisation following the Java package naming conventions.

The values of the `capabilities` object will depend on the capability
identifier, though in general the empty object will suffice.

The server should reply with a list of the operations the client may perform,
as shown:

```json
{
"capabilities": {
"m.capability_one": {}
}
}
```

The server should exclude from the list any operations which the client cannot
currently perform. It should also exclude any capabilities it does not
recognise or support, or whose value in the query did not have the expected
form.
richvdh marked this conversation as resolved.
Show resolved Hide resolved

Again the values of the `capabilities` object will depend on the capability
identifier.

### Initial capability identifiers
richvdh marked this conversation as resolved.
Show resolved Hide resolved

As a starting point, a single capability identifier is proposed:
`m.change_password`, which should be considered supported if it is possible to
change the user's password via the `POST /_matrix/client/r0/account/password`
API.

The values of the `capabilities` object should be the empty object in both the
query and the response.
richvdh marked this conversation as resolved.
Show resolved Hide resolved

### Fallback behaviour

Clients will need to be aware of servers which do not support the new endpoint,
and fall back to their current behaviour if they receive a 404 response.

## Tradeoffs
richvdh marked this conversation as resolved.
Show resolved Hide resolved

One alternative would be to provide specific ways of establishing support for
each operation: for example, a client might send an `GET
/_matrix/client/r0/account/password` request to see if the user can change
their password. The concern with this approach is that this could require a
large number of requests to establish which entries should appear on a menu or
dialog box.

Another alternative would be a simple `GET /_matrix/client/r0/capabilities`
query, where a server would return all possible supported operations. The
problem with this is that it may add load to the server, and increase network
traffic, by returning a large number of features which the client may have no
interest in.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds slightly spurious to me, tbh. You'd need quite a large set of capabilities before it'd be noticeable I'd have thought (especially when using compression). I also wouldn't expect it be queried very often by clients, so compared to /sync and co I think the traffic/load would be negligible?

OTOH, I'm not against using a POST, though I kinda expect a lot of folks to ask why they can't simply do a GET (I could certainly see myself wanting to query everything to debug what's going on)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern is less about network traffic and more about a world where a server is divided up into microservices so has to go and ask lots of other bits of the system for answers on the capabilities - or even just do database queries or whatever.

richvdh marked this conversation as resolved.
Show resolved Hide resolved

## Potential issues

None yet identified.

## Security considerations

None yet identified.

## Conclusion

We propose adding a new endpoint to the Client-Server API, which will allow
clients to query for supported operations so that they can decide whether to
expose them in their user-interface.