jami-docs/technical/Name-Server-Protocol.md

209 lines
5.7 KiB
Markdown

The protocol used by Jami to query and register a name is based on an
HTTP
[REST](https://en.wikipedia.org/wiki/Representational_state_transfer)
API answering requests with JSON documents and regular HTTP status
codes.
The public nameserver is hosted at `ns.jami.net` and uses a blockchain as
its backend. Another implementation could use any other database or
directory service making the nameserver protocol reusable.
Rules on name formatting
------------------------
Usernames are checked by a regex to ensure some rules about their
format:
- Length must be between 3 and 32 characters
- Those characters must be alphanumerical with underscore `_` being
also accepted.
Querying a name
---------------
This is the main service provided by a name server. It enables to get
the RingID corresponding to a username.
### Request
A request for the name `foobar` is a `GET` request with
`/name/`*`foobar`* as the URI.
### Response (Success)
If the name is found, a response with status code `200` `OK` must be
sent to the client with a `Content-type` field set as
`application/json`.
The body is a JSON documents with 2 string attributes : `name` and
`addr`. `name` is equal to the one requested and `addr` is an
hexadecimal representation of the RingID prefixed with `0x`.
In our example, the JSON answer would be:
``` {.javascript}
{
"name":"foobar",
"addr":"0x29347542eb07159f316577e1ae16243d152f6b7b"
}
```
### Response (Not found)
If the name is not found, a response with status code `404` `Not`
`Found` must be sent to the client with a `Content-type` field set as
`application/json`.
The body is a JSON documents with 1 string attribute : `error`. This
attribute is filled with an error message that explains the error (and
could be displayed in the client in the future).
On the reference implementation, the returned document is:
``` {.javascript}
{
"error":"name not registred"
}
```
Querying an address
-------------------
This service is a reverse lookup. You query for an address and a
username is returned if one is registered on the name server.
### Request
A request for the ID `ring:29347542eb07159f316577e1ae16243d152f6b7b`
is a `GET` request with
`/addr/`*`29347542eb07159f316577e1ae16243d152f6b7b`* as the URI.
### Response (Success)
If the address corresponds to a username, a response with status code
`200` `OK` must be sent to the client with a `Content-type` field set as
`application/json`.
The body is a JSON documents with 1 string attribute : `name`. The value
of this field is the name registered to this address
In our example, the JSON answer would be:
``` {.javascript}
{
"name":"foobar"
}
```
### Response (Not found)
If the address is not found, a response with status code `404` `Not`
`Found` must be sent to the client with a `Content-type` field set as
`application/json`.
The body is a JSON documents with 1 string attribute : `error`. This
attribute is filled with an error message that explains the error (and
could be displayed in the client in the future).
On the reference implementation, the returned document is:
``` {.javascript}
{
"error":"address not registred"
}
```
Registering a name
------------------
This part of the protocol is used to register a new name/address pair.
It is used on the main public registry but may be optional in a custom
implementation.
### Request
A request for registering the name `foobar` is a `POST` request with
`/name/`*`foobar`* as the URI. The header attribute `Content-type` must
be set to `application/json`.
The body of the request is a JSON document with 2 string attributes:
`addr` and `owner`. `addr` contains the RingID prefixed with `0x` and
`owner` is the name to be registered.
An example for `foobar` could be:
``` {.javascript}
{
"addr":"0x29347542eb07159f316577e1ae16243d152f6b7b",
"owner":"foobar"
}
```
### Response (Success)
If the name/address pair is successfully registered, a response with
status code `200` `OK` must be sent to the client with a `Content-type`
field set as `application/json`.
The body contain a JSON document with 1 boolean attribute `success` set
to `true`.
As an example:
``` {.javascript}
{
"success":true
}
```
Further attempts to query the name or the address should then be
successful.
### Response (Bad request)
If the registration cannot be achieved because of an error in the
request (formatting, missing attribute, etc.), a response with status
code `400` `Bad` `Request` must be sent to the client with a
`Content-type` field set as `application/json`.
The body is a JSON documents with 2 attributes: `success` which is a
boolean and `error` which is a string. `success` is set to `false` and
`error` is filled with an error message that explains the error (and
could be displayed in the client in the future).
For an invalid formatting of the username, the body could be:
``` {.javascript}
{
"success": false,
"error": "invalid name"
}
```
### Response (Forbidden)
If the registration cannot be achieved because the name is already
taken, a response with status code `403` `Forbidden` must be sent to the
client with a `Content-type` field set as `application/json`.
The body is a JSON documents with 3 attributes: `success` which is a
boolean set to `false`, `name` and `addr` which are both strings
replicated from the original request.
Registering `foobar`, with it being already registered, would lead to
the following response:
``` {.javascript}
{
"success": false,
"name":"foobar",
"addr":"0x29347542eb07159fdeadbeefae16243d152f6b7b"
}
```
Some links
----------
- [ring-nameservice](https://github.com/savoirfairelinux/ring-nameservice):
reference NodeJS implementation used by `ns.ring.cx` and querying an
Ethereum node.