UI API Documentation
There are several ways to communicate with the qaul.net daemon. They all have the same functionality and communicate via JSON over http. If you want to create an UI client for qaul.net this guide documents how to interact with the daemon.
JSON-RPC API
The JSON-RPC API uses a single http endpoint for the communication with qaul daemon. It is our main API for UI's.
HTTP-API
The HTTP-API is the main entry point for the Web-GUI. It uses the http protocol for the communcation and communicates with the EmberJS REST module in the qaul.net WebGUI.
JSON-RPC API
The JSON-RPC API consists of a single http endpoint. Over which all RPC interaction with the qaul.net daemon happens.
General Concept
The JSON-RPC API's prefix is /rpc
.
All requests are sent as POST requests to this endpoint and will return with http response code 200.
Request
The general JSON-RPC JSON structure looks like this:
{
"id": "RANDOM_REQUEST_ID",
"kind": "MODEL_NAME",
"method": "METHOD_NAME",
"data": {
"field_name": "FIELD_VALUE",
"field_name": "FIELD_VALUE"
},
"auth": {
"id": "USER_ID",
"token": "SESSION_TOKEN"
}
}
The method name can have one of those values:
- create: When you're creating a new entry.
- get: To request one entry by ID.
- modify: To modify an entry.
- delete: To delete one entry by ID.
- list: To receive a list of queried entries.
There are some special authentication methods:
- login: to start an authenticated session
- logout: to terminate an authenticated session
- validate: to validate a session token
Request Data Payload
In order to create or modify an entry we send a JSON payload with the request.
To create an entry we send POST a request with the content of some of the fields. Please be aware, that some fields are mandatory and that not all the fields can be set during the creation of an entry. To find out about the specific use please check the documentation of the model.
Create entry payload example:
{
"field_name": "FIELD_VALUE"
}
To modify and entry we send a PATCH request with only the modified fields in a specific structure. A set structure to set or modify a field, and an unset structure to delete the content of a field.
Modify entry payload example:
{
"field_name": { "set": "FIELD_VALUE" },
"field_name": "unset"
}
Response
The general response payload structure looks like this:
{
"id": "RANDOM_REQUEST_ID",
"kind": "MODEL_NAME",
"method": "METHOD_NAME",
"data": {
"field_name": "FIELD_VALUE"
}
}
The "data" field has several specific structures that are documented in the following.
Response Data Payload per Action
The response payloads are model specific and should be checked in the model documentations. however there are some general rules how a payload looks.
When you're requesting a list of entries, you're receiving the following structure:
{
"id": "RANDOM_REQUEST_ID",
"kind": "MODEL_NAME",
"method": "METHOD_NAME",
"data": {
"model_name": [
{
"id": "ITEM_ID",
"field_name": "FIELD_CONTENT"
},
{
"id": "ITEM_ID",
"field_name": "FIELD_CONTENT"
}
]
}
}
When you get one specific entry by it's ID, or when you create or modify an entry you're receiving the following structure:
{
"id": "RANDOM_REQUEST_ID",
"kind": "MODEL_NAME",
"method": "METHOD_NAME",
"data": {
"model_name": {
"id": "ITEM_ID",
"field_name": "FIELD_CONTENT"
}
}
}
Sometimes you're only receiving a success message as data payload.
{
"id": "RANDOM_REQUEST_ID",
"kind": "MODEL_NAME",
"method": "METHOD_NAME",
"data": {
"type": "success"
}
}
Error Response Data Payload
On error you're receiving an error message as data payload.
{
"id": "RANDOM_REQUEST_ID",
"kind": "MODEL_NAME",
"method": "METHOD_NAME",
"data": {
"error": "ERROR_MESSAGE"
}
}
Test JSON RPC API
There are shell scripts over which you can test all the functions of the JSON RPC API.
The bash test scripts are located in the folder tests/json-rpc of the qaul.net repository.
How to execute and use the test scripts is documented in the README.md file in the test script folder.
HTTP API
The HTTP API uses specific http URLs, http request codes and http response codes for each function. It is the API used by the webGUI.
General Concept
The HTTP API's prefix is /http
.
Model names and field id's use snake case in singular. URL's always use the model name in singular. If the return is an array of multiple objects or object id's then the field name is in plural.
The model content has the following JSON structure:
id
contains the model ID as a string:"id": "ID_STRING"
- one to one relationships should reference the model name in singular with the referenced ID string:
"model_name": "ID_STRING"
- one to many relationships should be built using the model name in plural followed by an array of the referenced ID's:
"model_names": [ ARRAY_OF_ID_STINGS ]
Request
URL Concept
The general URL concept looks like this:
/http/model_name/ID?QUERY_STRING
To list all entries:
GET /http/model_name
To query the entries:
GET /http/model_name?QUERY_STRING
To create a new entry:
POST /http/model_name
To get a single entry:
GET /http/model_name/ID
To modify an entry:
PATCH /http/model_name/ID
To delete an entry:
DELETE /http/model_name/ID
Authentication
The Authentication Token is sent in the Authorization
field of the http request header.
Authorization:{"id":"USER_ID","token":"SESSION_TOKEN"}
Payload
In order to create or modify an entry we send a JSON payload with the request.
To create an entry we send POST a request with the content of some of the fields. Please be aware, that some fields are mandatory and that not all the fields can be set during the creation of an entry. To find out about the specific use please check the documentation of the model.
Create entry payload example:
{
"field_name": "FIELD_VALUE"
}
To modify and entry we send a PATCH request with only the modified fields in a specific structure. A set structure to set or modify a field, and an unset structure to delete the content of a field.
Modify entry payload example:
{
"field_name": { "set": "FIELD_VALUE" },
"field_name": "unset"
}
Response
HTTP Response Codes
HTTP response codes on success:
- 200 (OK): default response code, when everything went well and you're receiving a payload.
- 204 (No Content): response when there is no payload, which you get on delete and sometimes on modify too.
HTTP response codes on error:
- 400 (Bad Request): wrong user input (and any other unhandled error)
- 401 (Unauthorized): if the user is not authorized to perform this task. This either means that you're authorization token is invalid or that you're trying to access some other users data.
- 500 (Internal Server Error): The server was not able to parse the request payload.
Response Payload per Action
The response payloads are model specific and should be checked in the model documentations. however there are some general rules how a payload looks.
When you're receiving a list of entries, you're receiving the following structure:
{
"model_names": [
{
"id": "ITEM_ID",
"field_name": "FIELD_CONTENT"
},
{
"id": "ITEM_ID",
"field_name": "FIELD_CONTENT"
}
]
}
When you get one specific entry by it's ID, or when you create a new entry you're receiving the following structure:
{
"model_name": {
"id": "ITEM_ID",
"field_name": "FIELD_CONTENT"
}
}
Error Response Payload
On error you're receiving an error message as payload.
{
"error": "ERROR_MESSAGE"
}
Authentication HTTP-API Interface
Each client needs to authenticate a session in order to be able to interact with the qaul.net daemon and send the session authentication in the http Authorization
header.
Http Authorization Header
The session authentication needs to be sent Authorization
field of the http request header.
Authorization:{"id":"USER_ID","token":"SESSION_TOKEN"}
Unauthenticated Functions
There are a few HTTP-API calls can be made without sending a session authorization. This is the list of the calls. If a session authorization header is sent, it will be ignored.
GET /http/user
: get a list of all users on this node.POST /http/user
: create a new user.GET /http/user/ID
: get the information of a specific user by it'sID
.POST /http/auth
: create a new authenticated session.
Login
In order to create an authentication session, the user needs to login.
Login request:
POST /http/auth
{
"id": "USER_ID",
"pw": "PASSWORD"
}
Login response payload:
{
"auth": {
"id": "USER_ID",
"token": "AUTHENTICATION_TOKEN"
}
}
Logout
To end and logout of an authenticated session you must send the following request:
DELETE /http/auth
On success it returns with http code 204.
Check whether a Session Authentication Token is still Valid
To check whether an authenticated session is still valid, you can send the following request:
GET /http/auth
It returns http code 204 on success and 401 on failure.
User HTTP-API Interface
The user api reflects all user accounts on the local the node. All information except password is available to other users.
User Model
{
"user": {
"avatar": null,
"bio": {
"key":"VALUE"
},
"display_name": null,
"id": "USER_ID",
"real_name": null,
"services": []
}
}
Create User
To create a user, one must only send a password.
POST /http/user
Request payload:
{
"pw":"PASSWORD"
}
Response payload: user model
{
"user": {
"avatar": null,
"bio": {},
"display_name": null,
"id": "USER_ID",
"real_name": null,
"services": []
}
}
Modify User
POST /http/user/USER_ID
Request payload: Only the changed fields are sent in the diff format.
{
"display_name": {
"set": "testuser"
},
"real_name": {
"set": "My Real Name"
}
}
Response: same as create user
Get Information of a Specific User
GET /http/user/USER_ID
Response: same as create user
Delete a User
DELETE /http/user/USER_ID
Request payload: There needs to be sent the field "purge", which can be set to the string values "true" or "false". If the value is "true", all data of the user is deleted from the node.
{
"purge": "true"
}
Response: empty response with http code 204
Query Users
Get an array of all users on the local node.
GET /http/user
Response payload: array of users
{
"users": [
{
"avatar": null,
"bio": {},
"display_name": "nameofuser1",
"id": "USER_ID",
"real_name": "Real Name",
"services": []
},
{
"avatar": null,
"bio": {},
"display_name": null,
"id": "USER_ID",
"real_name": null,
"services": []
}
]
}
Contact HTTP-API Interface
The contact api reflects all users on all remote nodes. The users on the local node are not shown. The Model of the contact is the same as the user model.
Contact Model
{
"user": {
"avatar": null,
"bio": {
"key":"VALUE"
},
"display_name": null,
"id": "USER_ID",
"real_name": null,
"services": []
}
}
Query Contacts
Get an array of all discovered users on all remote nodes.
GET /http/contact
Response payload: array of users
{
"users": [
{
"avatar": null,
"bio": {},
"display_name": "nameofuser1",
"id": "USER_ID",
"real_name": "Real Name",
"services": []
},
{
"avatar": null,
"bio": {},
"display_name": null,
"id": "USER_ID",
"real_name": null,
"services": []
}
]
}
Chat Service HTTP-API Interface
The chat service consists of two models, the chat_room
and the chat_message
. First there needs to be created a chat_room
with as many participants as desired. Afterwards one can send a chat_message
to a chat_room
.
Chat Models
Chat room model
{
"chat_room": {
"create_time": "2020-06-22T13:19:41.143402587Z",
"id": "CHAT_ROOM_ID",
"name": "CHAT ROOM NAME",
"users": [
"USER_ID",
"USER_ID"
]
}
}
Chat message model
{
"chat_message": {
"content": "TEXT_MESSAGE",
"id": "CHAT_MESSAGE_ID",
"room": {
"Id": "CHAT_ROOM_ID"
},
"sender": "USER_ID",
"timestamp": "2020-06-22T13:26:37.478641925Z"
}
}
Non standard behaviour: Please be aware that the chat_room relationship has a non standard notation:
"room": {"Id": "CHAT_ROOM_ID"}
This will hopefully change in the future.
Chat Room
Create Chat Room
To create a chat room one can send an array of user id's and an optional chat room name.
POST /http/chat_room
Request payload:
{
"name": "CHAT ROOM NAME",
"users": [
"USER_ID",
"USER_ID"
]
}
Response payload:
{
"chat_room":{
"id":"CHAT_ROOM_ID",
"users":[
"USER_ID",
"USER_ID",
"SENDER_USER_ID"
],
"name":"CHAT ROOM NAME",
"create_time":"2020-06-22T14:21:24.311261408Z"
}
}
Modify Chat Room
Change
PATCH /http/chat_room/CHAT_ROOM_ID
Request payload: Only the changed fields are sent in the diff format.
{
"id": "CHAT_ROOM_ID",
"set": {
"name": "My Room Name"
}
}
Response payload: same as create chat room.
Get Chat Room
Retrieve the information of a specific chat room by it's id.
GET /http/chat_room/CHAT_ROOM_ID
Response payload: same as create chat room.
List all Chat Rooms
GET /http/chat_room
Response payload: Array of chat rooms
{
"chat_rooms": [
"ARRAY_OF_CHAT_ROOM_OBJECTS"
]
}
Chat Message
Create a Chat Message
POST /http/chat_message
Request payload:
{
"room": "CHAT_ROOM_ID",
"text": "MESSAGE_TEXT"
}
Response payload: returns created chat message
{
"chat_message": {
"content": "MESSAGE_TEXT",
"id": "CHAT_MESSAGE_ID",
"room": {
"Id": "CHAT_ROOM_ID"
},
"sender": "USER_ID",
"timestamp": "2020-06-22T16:46:03.317992177Z"
}
}
List all Chat Messages of a Specific Chat Room
GET /http/chat_message?chat_room=CHAT_ROOM_ID
Response payload: Array of chat messages
{
"chat_messages": [
"ARRAY_OF_CHAT_MESSAGE_OBJECTS"
]
}
Test The HTTP API
There are shell scripts over which you can test all the functions of the HTTP API.
The bash test scripts are located in the folder tests/http-api of the qaul.net repository.
How to execute and use the test scripts is documented in the README.md file in the test script folder.