Server API
HTTP API is a way to send commands to Centrifugo. There is also another way to send commands – using Redis engine but in this chapter we will talk mostly about HTTP API.
Why we need API?
If you look at project and namespace options you see option called publish
. When turned on
this option allows browser clients to publish into channels directly. If client publishes a
message into channel directly - your application will not receive that message (it just goes
through Centrifugo towards subscribed clients). This pattern can be useful sometimes but in
most cases you first need to receive new event from client via AJAX, process it - probably
validate, save into database and then publish
into Centrifugo using HTTP API and Centrifugo
will then broadcast message to all subscribed clients.
Also HTTP API can be used to send other types of commands - see all available commands below.
If your backend written in Python you can use Cent API client. Also we have client for Ruby and PHP. If you use other language don't worry - I will describe how to communicate with Centrifugo HTTP API endpoint in this chapter.
Note also that there are 2 API endpoints in Centrifugo - first of them is HTTP API endpoint and
second – Redis Engine API. In this section we will talk about HTTP API mostly. You can find
description of Redis API in engines
chapter - it has the same commands but simplified format.
So if you decide that HTTP API is too difficult and uncomfortable to use - you can use Redis API
to publish new messages into channels.
Let's start!
Centrifugo API url is /api/
.
So if your Centrifugo sits on domain https://centrifuge.example.com
then an API address
will be https://centrifuge.example.com/api/
.
All you need to do to use HTTP API is to send correctly constructed POST request to this endpoint.
API request is a POST application/json
request with commands in request body and one additional header X-API-Sign
.
Body of request is just a JSON representing commands you need to execute. This can be single command or array of commands. See available commands below.
X-API-Sign
header is an SHA-256 HMAC string based on Centrifugo secret key and JSON body you want to send.
This header is used by Centrifugo to validate API request. In most situations you can protect Centrifugo
API endpoint with firewall rules and disable sign check using --insecure_api
option when starting
Centrifugo. In this case you just need to send POST request with commands - no need in addition header.
Command is a JSON object with two properties: method
and params
.
method
is a name of action you want to do.
params
is an object with method arguments.
For example to send publish command to Centrifugo in Python you construct sth like this for your request body:
command = json.dumps({
"method": "publish",
"params": {"channel": "news", data:{}}
})
If you have not turned of sign check you also need to include properly constructed sign
in X-API-Sign
header when sending this to /api/
Centrifugo endpoint.
To send 2 publish commands in one request you need body like this:
commands = json.dumps([
{
"method": "publish",
"params": {"channel": "news", data:{"content": "1"}}
},
{
"method": "publish",
"params": {"channel": "news", data:{"content": "2"}}
}
])
First lets see how to construct such request in Python.
If Python is your language then you don't have to implement this yourself as
Cent
python module exists.
But this example here can be useful for someone who want to implement interaction with Centrifugo API in language for which we don't have API client yet or you just want to send requests yourself - this is simple and in most cases you can just go without using our API library (to not introduce extra dependency in your project for example).
Let's imagine that your Centrifugo has secret key secret
.
First, let's see how to send API command using Python library requests
:
import json
import requests
from cent.core import generate_api_sign
commands = [
{
"method": "publish",
"params": {"channel": "docs", "data": {"content": "1"}}
}
]
encoded_data = json.dumps(commands)
sign = generate_api_sign("secret", encoded_data)
headers = {'Content-type': 'application/json', 'X-API-Sign': sign}
r = requests.post("https://centrifuge.example.com/api/", data=encoded_data, headers=headers)
print r.json()
In code above to generate sign we used function from Cent
module. To see how you can
generate API sign yourself go to chapter Tokens and signatures.
Also note that in this example we send an array of commands. In this way you can send several commands to Centrifugo in one request.
There are not so many commands you can call. The main and most useful of them is publish
.
Lets take a closer look on other available API command methods.
You have publish
, broadcast
, unsubscribe
, presence
, history
, disconnect
,
channels
, stats
, node
in your arsenal.
publish
publish
allows to send message into channel. params
for publish
method must be an
object with two keys: channel
and data
which contains valid JSON payload you want to
send into channel.
{
"method": "publish",
"params": {
"channel": "CHANNEL NAME",
"data": {
"input": "hello"
}
}
}
Starting with version 0.2.0 there is an option to include client
ID into publish API command:
{
"method": "publish",
"params": {
"channel": "CHANNEL NAME",
"data": {
"input": "hello"
},
"client": "long-unique-client-id"
}
}
In most cases this is a client
ID that initiated this message. This client
will
be then added on top level of published message.
Response example:
{
"body": null,
"error": null,
"method": "publish"
}
broadcast (new in v1.2.0)
Very similar to publish
but allows to send the same data into many channels.
{
"method": "broadcast",
"params": {
"channels": ["CHANNEL_1", "CHANNEL_2"],
"data": {
"input": "hello"
}
}
}
client
field to set client ID also supported.
This command will publish data into channels until first error happens. This error then set as response error and publishing stops. In case of using Redis API queue first error will be logged.
unsubscribe
unsubscribe
allows to unsubscribe user from channel. params
is an objects with two
keys: channel
and user
(user ID you want to unsubscribe)
{
"method": "unsubscribe",
"params": {
"channel": "CHANNEL NAME",
"user": "USER ID"
}
}
Response example:
{
"body": null,
"error": null,
"method": "unsubscribe"
}
disconnect
disconnect
allows to disconnect user by its ID. params
in an object with user
key.
{
"method": "disconnect",
"params": {
"user": "USER ID"
}
}
Response example:
{
"body": null,
"error": null,
"method": "disconnect"
}
presence
presence
allows to get channel presence information (all clients currently subscribed on
this channel). params
is an object with channel
key.
{
"method": "presence",
"params": {
"channel": "CHANNEL NAME"
}
}
Response example:
{
"body": {
"channel": "$public:chat",
"data": {
"a1c2f99d-fdaf-4e00-5f73-fc8a6bb7d239": {
"user": "2694",
"client": "a1c2f99d-fdaf-4e00-5f73-fc8a6bb7d239",
"default_info": {
"first_name": "Alexandr",
"last_name": "Emelin"
},
"channel_info": {
"channel_extra_info_example": "you can add additional JSON data when authorizing"
}
},
"e5ee0ab0-fde1-4543-6f36-13f2201adeac": {
"user": "2694",
"client": "e5ee0ab0-fde1-4543-6f36-13f2201adeac",
"default_info": {
"first_name": "Alexandr",
"last_name": "Emelin"
},
"channel_info": {
"channel_extra_info_example": "you can add additional JSON data when authorizing"
}
}
}
},
"error": null,
"method": "presence"
}
history
history
allows to get channel history information (list of last messages sent into channel).
params
is an object with channel
key.
{
"method": "history",
"params": {
"channel": "CHANNEL NAME"
}
}
Response example:
{
"body": {
"channel": "$public:chat",
"data": [
{
"uid": "8c5dca2e-1846-42e4-449e-682f615c4977",
"timestamp": "1445536974",
"info": {
"user": "2694",
"client": "a1c2f99d-fdaf-4e00-5f73-fc8a6bb7d239",
"default_info": {
"first_name": "Alexandr",
"last_name": "Emelin"
},
"channel_info": {
"channel_extra_info_example": "you can add additional JSON data when authorizing"
}
},
"channel": "$public:chat",
"data": {
"input": "world"
},
"client": "a1c2f99d-fdaf-4e00-5f73-fc8a6bb7d239"
},
{
"uid": "63ecba35-e9df-4dc6-4b72-a22f9c9f486f",
"timestamp": "1445536969",
"info": {
"user": "2694",
"client": "a1c2f99d-fdaf-4e00-5f73-fc8a6bb7d239",
"default_info": {
"first_name": "Alexandr",
"last_name": "Emelin"
},
"channel_info": {
"channel_extra_info_example": "you can add additional JSON data when authorizing"
}
},
"channel": "$public:chat",
"data": {
"input": "hello"
},
"client": "a1c2f99d-fdaf-4e00-5f73-fc8a6bb7d239"
}
]
},
"error": null,
"method": "history"
}
channels (Centrifugo >= 0.3.0)
channels
method allows to get list of active (with one or more subscribers) channels.
{
"method": "channels",
"params": {}
}
Response example:
{
"body": {
"data": [
"$public:chat",
"news",
"notifications"
]
},
"error": null,
"method": "channels"
}
stats (Centrifugo >= 1.0.0)
stats
method allows to get statistics about running Centrifugo nodes.
{
"method": "stats",
"params": {}
}
Response example:
{
"body": {
"data": {
"nodes": [
{
"uid": "6045438c-1b65-4b86-79ee-0c35367f29a9",
"name": "MacAir.local_8000",
"num_goroutine": 21,
"num_clients": 0,
"num_unique_clients": 0,
"num_channels": 0,
"started_at": 1445536564,
"gomaxprocs": 1,
"num_cpu": 4,
"num_msg_published": 0,
"num_msg_queued": 0,
"num_msg_sent": 0,
"num_api_requests": 0,
"num_client_requests": 0,
"bytes_client_in": 0,
"bytes_client_out": 0,
"memory_sys": 7444728,
"cpu_usage": 0
}
],
"metrics_interval": 60
}
},
"error": null,
"method": "stats"
}
node (Centrifugo >= 1.4.0)
node
method allows to get information about single Centrifugo node. That information
will contain counters without aggregation over minute interval (what stats
method
does by default). So it can be useful if your metric aggregation system aggregates counters
over time period itself. Also note that to use this method you should send API request
to each Centrifugo node separately - as this method returns current raw statistics about
node. See issue for motivation
description.
{
"method": "node",
"params": {}
}
Response example:
{
"body": {
"data":{
"uid":"c3ceab87-8060-4c25-9cb4-94eb9db7899a",
"name":"MacAir.local_8000",
"num_goroutine":14,
"num_clients":0,
"num_unique_clients":0,
"num_channels":0,
"started_at":1455450238,
"gomaxprocs":4,
"num_cpu":4,
"num_msg_published":0,
"num_msg_queued":0,
"num_msg_sent":0,
"num_api_requests":3,
"num_client_requests":0,
"bytes_client_in":0,
"bytes_client_out":0,
"memory_sys":0,
"cpu_usage":0
}
},
"error":null,
"method":"node"
}
Note again that there is existing API clients for Python, Ruby, PHP - so you don't have to construct these commands manually. If you use another programming languages look at existing clients to get more help implementing call to HTTP API.