Move client-server intro to client-server section

pull/977/head
Daniel Wagner-Hall 9 years ago
parent 1e27b104dd
commit ad4d8ae7a6

@ -17,6 +17,115 @@ shortly.
Documentation for the old `V1 authentication
<../attic/v1_registration_login.rst>`_ is still available separately.
API Standards
-------------
.. TODO
Need to specify any HMAC or access_token lifetime/ratcheting tricks
We need to specify capability negotiation for extensible transports
The mandatory baseline for communication in Matrix is exchanging JSON objects
over HTTP APIs. HTTPS is mandated as the baseline for server-server
(federation) communication. HTTPS is recommended for client-server
communication, although HTTP may be supported as a fallback to support basic
HTTP clients. More efficient optional transports for client-server
communication will in future be supported as optional extensions - e.g. a
packed binary encoding over stream-cipher encrypted TCP socket for
low-bandwidth/low-roundtrip mobile usage. For the default HTTP transport, all
API calls use a Content-Type of ``application/json``. In addition, all strings
MUST be encoded as UTF-8. Clients are authenticated using opaque
``access_token`` strings (see `Client Authentication`_ for details), passed as a
query string parameter on all requests.
Any errors which occur at the Matrix API level MUST return a "standard error
response". This is a JSON object which looks like::
{
"errcode": "<error code>",
"error": "<error message>"
}
The ``error`` string will be a human-readable error message, usually a sentence
explaining what went wrong. The ``errcode`` string will be a unique string
which can be used to handle an error message e.g. ``M_FORBIDDEN``. These error
codes should have their namespace first in ALL CAPS, followed by a single _ to
ease separating the namespace from the error code. For example, if there was a
custom namespace ``com.mydomain.here``, and a
``FORBIDDEN`` code, the error code should look like
``COM.MYDOMAIN.HERE_FORBIDDEN``. There may be additional keys depending on the
error, but the keys ``error`` and ``errcode`` MUST always be present.
Some standard error codes are below:
:``M_FORBIDDEN``:
Forbidden access, e.g. joining a room without permission, failed login.
:``M_UNKNOWN_TOKEN``:
The access token specified was not recognised.
:``M_BAD_JSON``:
Request contained valid JSON, but it was malformed in some way, e.g. missing
required keys, invalid values for keys.
:``M_NOT_JSON``:
Request did not contain valid JSON.
:``M_NOT_FOUND``:
No resource was found for this request.
:``M_LIMIT_EXCEEDED``:
Too many requests have been sent in a short period of time. Wait a while then
try again.
Some requests have unique error codes:
:``M_USER_IN_USE``:
Encountered when trying to register a user ID which has been taken.
:``M_ROOM_IN_USE``:
Encountered when trying to create a room which has been taken.
:``M_BAD_PAGINATION``:
Encountered when specifying bad pagination query parameters.
.. _sect:txn_ids:
The Client-Server API typically uses ``HTTP POST`` to submit requests. This
means these requests are not idempotent. The C-S API also allows ``HTTP PUT`` to
make requests idempotent. In order to use a ``PUT``, paths should be suffixed
with ``/{txnId}``. ``{txnId}`` is a unique client-generated transaction ID which
identifies the request, and is scoped to a given Client (identified by that
client's ``access_token``). Crucially, it **only** serves to identify new
requests from retransmits. After the request has finished, the ``{txnId}``
value should be changed (how is not specified; a monotonically increasing
integer is recommended). It is preferable to use ``HTTP PUT`` to make sure
requests to send messages do not get sent more than once should clients need to
retransmit requests.
Valid requests look like::
POST /some/path/here?access_token=secret
{
"key": "This is a post."
}
PUT /some/path/here/11?access_token=secret
{
"key": "This is a put with a txnId of 11."
}
In contrast, these are invalid requests::
POST /some/path/here/11?access_token=secret
{
"key": "This is a post, but it has a txnId."
}
PUT /some/path/here?access_token=secret
{
"key": "This is a put but it is missing a txnId."
}
Client Authentication
---------------------
Most API endpoints require the user to identify themselves by presenting

@ -358,112 +358,3 @@ dedicated API. The API is symmetrical to managing Profile data.
Would it really be overengineered to use the same API for both profile &
private user data, but with different ACLs?
API Standards
-------------
.. TODO
Need to specify any HMAC or access_token lifetime/ratcheting tricks
We need to specify capability negotiation for extensible transports
The mandatory baseline for communication in Matrix is exchanging JSON objects
over HTTP APIs. HTTPS is mandated as the baseline for server-server
(federation) communication. HTTPS is recommended for client-server
communication, although HTTP may be supported as a fallback to support basic
HTTP clients. More efficient optional transports for client-server
communication will in future be supported as optional extensions - e.g. a
packed binary encoding over stream-cipher encrypted TCP socket for
low-bandwidth/low-roundtrip mobile usage. For the default HTTP transport, all
API calls use a Content-Type of ``application/json``. In addition, all strings
MUST be encoded as UTF-8. Clients are authenticated using opaque
``access_token`` strings (see `Client Authentication`_ for details), passed as a
query string parameter on all requests.
Any errors which occur at the Matrix API level MUST return a "standard error
response". This is a JSON object which looks like::
{
"errcode": "<error code>",
"error": "<error message>"
}
The ``error`` string will be a human-readable error message, usually a sentence
explaining what went wrong. The ``errcode`` string will be a unique string
which can be used to handle an error message e.g. ``M_FORBIDDEN``. These error
codes should have their namespace first in ALL CAPS, followed by a single _ to
ease separating the namespace from the error code. For example, if there was a
custom namespace ``com.mydomain.here``, and a
``FORBIDDEN`` code, the error code should look like
``COM.MYDOMAIN.HERE_FORBIDDEN``. There may be additional keys depending on the
error, but the keys ``error`` and ``errcode`` MUST always be present.
Some standard error codes are below:
:``M_FORBIDDEN``:
Forbidden access, e.g. joining a room without permission, failed login.
:``M_UNKNOWN_TOKEN``:
The access token specified was not recognised.
:``M_BAD_JSON``:
Request contained valid JSON, but it was malformed in some way, e.g. missing
required keys, invalid values for keys.
:``M_NOT_JSON``:
Request did not contain valid JSON.
:``M_NOT_FOUND``:
No resource was found for this request.
:``M_LIMIT_EXCEEDED``:
Too many requests have been sent in a short period of time. Wait a while then
try again.
Some requests have unique error codes:
:``M_USER_IN_USE``:
Encountered when trying to register a user ID which has been taken.
:``M_ROOM_IN_USE``:
Encountered when trying to create a room which has been taken.
:``M_BAD_PAGINATION``:
Encountered when specifying bad pagination query parameters.
.. _sect:txn_ids:
The Client-Server API typically uses ``HTTP POST`` to submit requests. This
means these requests are not idempotent. The C-S API also allows ``HTTP PUT`` to
make requests idempotent. In order to use a ``PUT``, paths should be suffixed
with ``/{txnId}``. ``{txnId}`` is a unique client-generated transaction ID which
identifies the request, and is scoped to a given Client (identified by that
client's ``access_token``). Crucially, it **only** serves to identify new
requests from retransmits. After the request has finished, the ``{txnId}``
value should be changed (how is not specified; a monotonically increasing
integer is recommended). It is preferable to use ``HTTP PUT`` to make sure
requests to send messages do not get sent more than once should clients need to
retransmit requests.
Valid requests look like::
POST /some/path/here?access_token=secret
{
"key": "This is a post."
}
PUT /some/path/here/11?access_token=secret
{
"key": "This is a put with a txnId of 11."
}
In contrast, these are invalid requests::
POST /some/path/here/11?access_token=secret
{
"key": "This is a post, but it has a txnId."
}
PUT /some/path/here?access_token=secret
{
"key": "This is a put but it is missing a txnId."
}

Loading…
Cancel
Save