Transports
The DeepAffex Cloud API endpoints are available on HTTP REST and WebSocket transports. The DeepAffex Cloud does not limit access across different transports, so you may use the transports interchangeably.
For both the REST and the WebSocket transports, API endpoints are transacted using data in the JSON format. For WebSocket, Protocol buffers were an old legacy method used to encode data.
For simplicity, we will refer to "HTTP-based access using RESTful patterns" as the REST API and the WebSocket equivalent as the WebSocket API.
The REST API is available at https://api.deepaffex.ai. The WebSocket API is available at: wss://api.deepaffex.ai.1
Please note that there are different routing options available, please refer to the chapter on regions and clusters to know more about them.
An important difference between the REST and WebSockets API is that the
Measurements.Subscribe
endpoint is only available on the WebSocket API. This
endpoint is used to get real-time intermediate and final results of an active
measurement over a bidirectional WebSocket connection.
WebSockets
This transport method is highly optimized and provides a fast and efficient method of communicating with DeepAffex Cloud. We recommend using the WebSocket API for platforms where real-time results are required.
Connection
During connection creation, the string "json"
needs to be passed as the
WebSocket protocol to the server which indicates to the server that the client's
payloads will be JSON. To maintain a connection with the DeepAffex Cloud, you
must implement proper ping/pong heartbeats as required by the WebSocket standard
specification.
In addition to the standard use of WebSocket connectivity mechanics, the DeepAffex Cloud uses a custom request/response exchange pattern outlined below.
Request structure
A WebSocket request has to be a buffer, with the following structure:
Buffer( [ string:4 ][ string:10 ][ string/buffer:variablelength ] )
The first 4 bytes are an Action ID for the request, which is defined in the Endpoint Summary Table.
The next 10 bytes are a Request ID - a string identifier unique for each request. The client is responsible for creating a unique Request ID. It could be a counter or a randomly generated alphanumeric string e.g., "JDUEHDJEKO" or "000000001". This ID is only used within the current connection and does not interfere with other concurrent connections using the same token. Request IDs are not stored, so reusing them is possible however not recommended.
The remaining bytes represent the full body of your request in JSON format. In the legacy system, it used to be a serialized Protobuf. The DeepAffex Protobuf definitions are still available for download on the DeepAffex website.
Response structure
Requests that don't follow the structure defined above aren't processed. Instead, the following response is returned:
{
Code: "INCORRECT_REQUEST"
}
Correctly structured requests get responses with the following structure:
Buffer( [ string:10 ][ string:3 ][ string/buffer:variablelength ] )
The first 10 bytes are the Request ID matching a request to a response.
The next 3 bytes are an HTTP status identifier. Status codes are defined in the Header Response Codes Table.
The remaining bytes are the response body in JSON format. In the legacy system, it used to be a serialized Protobuf which could be deserialized using the DeepAffex Protobuf definitions.
The client needs to manage requests in memory and await the response asynchronously. The DeepAffex Cloud will always respond to a request to close it out, regardless of if there is an error or not. In addition, to the status code, the body will also contain relevant error information.
Details
An important difference in the call methods is translating query string and
parameters that would typically be sent via the REST service to the WebSocket
API. As an example, shown below are properties when making a request to the
Meta.retrieveByType
endpoint:
{
"Foo": "bar",
"Query": {
"Namespace": "all",
"Fields": "Foo,Bar"
},
"Params": {
"Type": "Group",
"ID": "7ab8bee7-808c-4123-9811-e385adb8c77d"
}
}
In essence Query
and Params
are values that are extracted from the payload
body and interpreted as values that would typically be expected by a REST
request.
Error messages are transported in turn in similar object formats as listed below. The WebSocket interface also follow this pattern.
Note: Many endpoints use arrays in the root of the payload. If you are still
using our old legacy method of Protobufs, then unfortunately Protobufs do not
support rooted arrays, hence the value needs to be wrapped in an object. The
DeepAffex Cloud looks for the Values
property in a payload and handles the
containing array as a root array. The following is an example of a request to
Groups.addUsers
:
REST request example:
[
"7ab8bee7-808c-4123-9811-ef85adb8c77f",
"7ab8bee7-808c-4123-9811-ef85adb8c75f",
"7ab8bee7-808c-4123-9811-ef85adb8c71f",
"7ab8bee7-808c-4123-9811-ef85adb8c72f",
"7ab8bee7-808c-4123-9811-ef85adb8c77f"
]
Protobuf wrapped example of the same payload:
{
"Values": [
"7ab8bee7-808c-4123-9811-ef85adb8c77f",
"7ab8bee7-808c-4123-9811-ef85adb8c75f",
"7ab8bee7-808c-4123-9811-ef85adb8c71f",
"7ab8bee7-808c-4123-9811-ef85adb8c72f",
"7ab8bee7-808c-4123-9811-ef85adb8c77f"
]
}
First steps
Upon connecting to the DeepAffex Cloud, we recommend checking the current API
version and general status. This is done by calling the General.Status
endpoint
which will respond with the appropriate status details. This endpoint does not
require any authentication.
For most other endpoints though, an appropriate Authorization header must be supplied. This is discussed in the next section.
For compatibility reasons, you can also use ports 9443 and 9080 for REST and WebSocket respectively but for new applications please use the default port, 443.