API #
Kuzzle exposes most of its features through a multi-protocol API.
This API uses the JSON format to communicate with a standardized request and response format.
Multi Protocol #
The Kuzzle API is accessible by default through 3 protocols:
Each protocol has advantages and disadvantages. The choice of a protocol must therefore be adapted to a situation and a use.
Kuzzle is able to integrate to its API any protocol operating on IP. More info on Writing Protocol Plugin.
Request Format #
Except for HTTP, Kuzzle expects the exact same request format for all communication protocols.
HTTP #
HTTP requests are split into the four HTTP usual parts: URL, verb, headers and body.
Every API action documentation has a dedicated HTTP section, explaining how to use that action with the HTTP protocol.
You can add the pretty
parameter in any HTTP URL to receive a pretty formatted JSON response. (e.g. GET "http://localhost:7512?pretty"
)
Optional Headers #
The following list of HTTP headers can be added to any and all HTTP requests:
Accept-Encoding
: compression algorithm(s) usable by Kuzzle to encode the response. Accepted encodings, in order of preference:gzip
,deflate
,identity
.Authorization
(expected value:Bearer <token>
): user's authentification token, obtained through the auth:login API actionContent-Encoding
: compression algorithm(s) used to encode the body sent to Kuzzle. Accepted encodings:deflate
,gzip
,identity
Body Encoding #
Body contents can be sent in the following formats:
application/json
: raw JSONmultipart/form-data
: HTML forms; both field-value pairs and field-files pairs can be sent that way
If a HTML form is sent that way, the resulting body content will be translated into a JSON object, with as many keys as the provided form fields. If the form field holds a file, then the corresponding JSON key will refer to an object instead of a mere value, with the following properties:
filename
: file's nameencoding
: file encodingmimetype
: MIME typefile
: file content, encoded in base64
JSON Query Endpoint #
Kuzzle also exposes an endpoint to send requests using the standard JSON request format used by other protocols.
This makes it possible to avoid the use of the REST API and to send requests via the HTTP protocol the same way as for any other protocols.
This endpoint is accessible with the route POST /_query
:
curl -X POST -H "Content-Type: application/json" "http://localhost:7512/_query" --data '{
"controller":"server",
"action":"now"
}'
The body of the request will be processed by Kuzzle as a standard request.
This endpoint does not allow to benefit from the advantages of the cache system integrated to HTTP via URLs.
Healthcheck endpoint #
Kuzzle exposes a healthcheck endpoint.
This endpoint is accessible with the route GET /_healthcheck
.
curl "http://localhost:7512/_healthcheck"
This route does not require any authentication. It returns a 200
status code if the server is up and running.
This is useful when kuzzle is deployed inside a Kubernetes cluster and you want to configure probes to check the server.
Other Protocols #
Kuzzle's extensible protocol system allows communication in virtually any format. This documentation section describes the format that must be used to pass requests to Kuzzle itself, either directly by users (for instance, using the embedded WebSocket or MQTT protocols), or indirectly, translated by the custom protocol layer.
Requests made to Kuzzle must be encoded using JSON, and have the following format:
{
// required by all requests
"controller": "<controller>",
"action": "<action>",
// optional, can be added to all requests
"requestId": "<unique request identifier>",
"jwt": "<token>",
// commonly found parameters
"index": "<index>",
"collection": "<collection>",
"body": {
// body content
},
"_id": "<unique ID>"
}
Required parameters #
The following 2 parameters are required by all API requests, as these are directly used by Kuzzle to redirect the request to the correct API action:
controller
: API controller nameaction
: API controller action to be executed
Depending on the API action executed, other parameters may be required. Those are detailed in the corresponding API sections.
Commonly found parameters: #
There are 3 parameters that can be provided to all requests, independently to the API action executed:
jwt
: user's authentification token, obtained through the auth:login methodrequestId
: user-defined request identifier. Kuzzle does not guarantee that responses are sent back in the same order than requests are made; use that field to link responses to their request of originvolatile
: user-defined data, without any impact to the request. Use that object to pass information about the request itself to real-time subscribers. Read more here
Additionally, a few other parameters are very commonly found in API requests:
_id
: unique identifier (e.g. document ID, user kuid, memory storage key, ...)body
: body content (e.g. document content, message content, mappings, ...)collection
: collection nameindex
: index name
Other parameters #
Kuzzle does not enforce a fixed list of parameters. Rather, API actions freely design the parameters list they need, and Kuzzle internal structures reflect that freedom. This principle is especially useful, as it allows applications and plugins to set their own list of required and optional parameters, without constraint.
Response Format #
Kuzzle Response are standardized. This format is shared by all API actions, including custom controller actions.
A Kuzzle Response is a JSON object with the following format:
Property | Description |
---|---|
action | API action |
collection | Collection name, or null if no collection was involved |
controller | API controller |
deprecations | If any, array of deprecation messages related to this action (only if NODE_ENV=development) |
error | KuzzleError object, or null if there was no error |
index | Index name, or null if no index was involved |
node | Unique identifier of the node who processed the request |
requestId | KuzzleRequest unique identifier |
result | Action result, or null if an error occured |
status | Response status, using HTTP status codes |
volatile | Arbitrary data repeated from the initial request |
Example: Display the entire response content of server:now action with Kourou
kourou server:now --display ""
# {
# "requestId": "60b6c20d-6cd6-4478-b2e0-5638475ae64b",
# "status": 200,
# "error": null,
# "controller": "server",
# "action": "now",
# "collection": null,
# "index": null,
# "node": "knode-nasty-author-4242",
# "volatile": {
# "sdkInstanceId": "d301a7c7-ed99-4ede-94c4-fb1dc2156789",
# "sdkName": "js@7.4.1"
# },
# "result": {
# "now": 1605000454514
# }
# }
Notification Format #
Kuzzle offers the possibility to receive real-time notifications through its Realtime Engine.
There are 3 types and formats of notifications:
- document
- user
- server
Document Notification #
Thoses notifications are either volatile Pub/Sub messages or Database Notifications occuring when documents change.
A document notification contains the following fields:
Property | Type | Description |
---|---|---|
action | string | API action |
collection | string | Collection name |
controller | string | API controller |
index | string | Index name |
node | string | Unique identifier of the node who generated the notification |
protocol | string | Network protocol used to modify the document |
result | object | Notification content |
room | string | Subscription channel identifier. Can be used to link a notification to its corresponding subscription |
scope | string | in : document enters (or stays) in the scopeout : document leaves the scope |
timestamp | number | Timestamp of the event, in Epoch-millis format |
type | string | document : the notification type |
volatile | object | KuzzleRequest volatile data |
The result
object is the notification content, and it has the following structure:
Property | Type | Description |
---|---|---|
_id | string | Document unique IDnull if the notification is from a real-time message |
_source | object | The message or full document content. |
_updatedFields | string[] | List of fields that have been updated (only available on document partial updates) |
Example: Document notification
{
"index": "tir-open-data",
"collection": "red-taxi",
"controller": "document",
"action": "create",
"protocol": "http",
"timestamp": 1497513122738,
"volatile": null,
"scope": "in",
"node": "knode-nasty-author-4242",
"result":{
"_source":{
"some": "document content",
"_kuzzle_info": {
"author": "-1",
"createdAt": 1497866996975
}
},
"_id": "<document identifier>"
},
"room":"893e183fc7acceb5-7a90af8c8bdaac1b"
}
User Notification #
User notifications are triggered by the following events:
- A user subscribes to the same room
- A user leaves that room
These notifications are sent only if the users argument is set to any other value than the default none
one.
A user notification contains the following fields:
Property | Type | Description |
---|---|---|
action | string | API action |
collection | string | Collection name |
controller | string | API controller |
index | string | Index name |
node | string | Unique identifier of the node who generated the notification |
protocol | string | Network protocol used by the entering/leaving user |
result | object | Notification content |
room | string | Subscription channel identifier. Can be used to link a notification to its corresponding subscription |
timestamp | number | Timestamp of the event, in Epoch-millis format |
type | string | user : the notification type |
user | string | in : a new user has subscribed to the same filtersout : a user cancelled a shared subscription |
volatile | object | KuzzleRequest volatile data |
The result
object is the notification content, and it has the following structure:
Property | Type | Description |
---|---|---|
count | number | Updated users count sharing that same subscription |
Example: User Notification
{
"index": "tir-open-data",
"collection": "red-taxi",
"controller": "realtime",
"action": "subscribe",
"protocol": "websocket",
"timestamp": 1497517009931,
"user": "in",
"node": "knode-nasty-author-4242",
"result": {
"count": 42
},
"volatile": {
"fullname": "John Snow",
"favourite season": "winter",
"goal in life": "knowing something"
}
}
Server Notification #
Server notifications are triggered by global events, and they are sent to all of a client's subscriptions at the same time.
Currently, the only event generating a server notification is when an authentication token has expired, closing the subscription.
The TokenExpired
server notification is only sent if the client has an active realtime subscription.
A server notification contains the following fields:
Property | Type | Value |
---|---|---|
message | string | Server message explaining why this notification has been triggered |
node | string | Unique identifier of the node who generated the notification |
type | string | TokenExpired : notification type |
Example: Server Notification
{
"message": "Authentication Token Expired",
"type": "TokenExpired"
}
Handling Errors #
Errors returned by the Kuzzle API in the error
part of a response are objects with the following properties:
Property | Type | Description |
---|---|---|
status | number | HTTP status code |
message | string | Short description of the error |
stack | string | Error stack trace (Available in development mode only) |
id | string | Error unique identifier |
code | number | Error unique code |
List of Standard Kuzzle Error
Example: Receving a network.http.url_not_found
curl "localhost:7512/_i_am_not_a_valid_url?pretty"
# {
# "requestId": "cbafaf6e-0464-4787-a2b4-633739e7c677",
# "status": 404,
# "error": {
# "message": "API URL not found: /_i_am_not_a_valid_url.",
# "status": 404,
# "id": "network.http.url_not_found",
# "code": 50397191
# },
# "controller": null,
# "action": null,
# "collection": null,
# "index": null,
# "volatile": null,
# "result": null
# }
id #
The id
property is unique to each type of error that can be returned, and is built by concatenating the following information:
- Domain: from where the error comes from (API, network, plugin, ...)
- Subdomain: what kind of error it is (assertion, runtime, ...)
- Error: the error itself
For instance:
api.assert.missing_argument
is an assertion error triggered by the API because of a missing argumentnetwork.http.url_not_found
is a HTTP error triggered by the network layer, because a requested URL couldn't be found
The complete list of API errors is available here.
code #
The code
property is a 32-bits integer representation of the unique id
error identifier, detailed above.
It's meant to be used by low-level languages to efficiently catch specific error codes and act on them.
Code format:
- Domain: ranges from
00
toFF
(1 byte) - Subdomain: ranges from
00
toFF
(1 byte) - Error: ranges from
0000
toFFFF
(2 bytes)
The complete list of API errors is available here.
Volatile Data #
All requests accept a volatile
object in parameter.
The content of this object is not meant to be used directly: it has no impact on the request itself.
Still, volatile data are not completely ignored by Kuzzle, and they have a few uses.
KuzzleRequest Context #
Volatile data can be used to provide additional context about a request; this allows extended logs, application metadata, and so on. Many use cases benefit from being able to pass context data, without any direct impact to requests themselves.
Lastly, if a request triggers a document notification, then its volatile data are included in the notification content. This allows real-time subscribers to get elements of context about changes made to documents, if needs be.
By default, SDKs includes two fields in the request volatile data:
sdkInstanceId
: unique identifier for this SDK instancesdkName
: SDK name and version
Realtime Subscription Context #
There is one special case, where volatile data are stored by Kuzzle for a later use, instead of being completely ignored: whenever a client make a new real-time subscription.
Volatile data passed to a new subscription query are used two times by Kuzzle:
- if the new subscription triggers document notification, its volatile data are included into those
- if that subscription is cancelled, whether because of a call to realtime:unsubscribe, or after the client disconnects: the volatile data provided at the time of the subscription are once again copied into user notifications triggered by that event
This allows other realtime subscribers to get context information about a client joining or leaving the same subscription as them.
Limits #
Kuzzle API has several protection mechanisms against Denial of Service Attacks (DoS).
These mechanisms are regulated by configurable limits.
Concurrent Requests #
Kuzzle has a limited number of requests that can be processed in parallel.
Once this number of requests is reached, new requests are stored in a queue before they can be processed when a slot becomes available.
Associated configuration keys:
limits.concurrentRequests
(50
): number of requests Kuzzle processes simultaneouslylimits.requestsBufferSize
(50000
): maximum number of requests that can be bufferedlimits.requestsBufferWarningThreshold
(5000
):number of buffered requests after which Kuzzle will throw core:overload events
Documents Limits #
Kuzzle limits the number of documents that can be read or written with the same request.
Associated configuration keys:
limits.documentsFetchCount
(10000
): maximum number of documents that can be fetched by a single API requestlimits.documentsWriteCount
(200
): maximum number of documents that can be written by a single API request
You may also change the value of the server.maxRequestSize
limit to make Kuzzle accept larger requests.
Realtime Engine Limits #
Kuzzle also makes it possible to control the use of the Realtime Engine.
Associated configuration keys:
limits.subscriptionConditionsCount
(16
): maximum number of conditions a subscription filter can containlimits.subscriptionMinterms
(0
): maximum number of minterms (AND) clauses after the filters are transformed in their Canonical Disjunctive Normal Formlimits.subscriptionRooms
(1000000
): maximum number of different subscription roomslimits.subscriptionDocumentTTL
(259200
): maximum time (in seconds) a document will be kept in cache for realtime subscriptions
Other Limits #
server.maxRequestSize
(1mb
): maximum size of an incoming request (e.g. "42mb")limits.loginsPerSecond
(1
): maximum number of logins per second and per network connection