<commit_before># Server HTTP API

HTTP API is a way to send commands to Centrifugo.

Why we need API?

If you look at configuration options you see an option called `publish` defined on configuration top level and for channel namespace. 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 send new event from client to backend over non-Centrifugo transport (for example via AJAX request in web application), then process it on application backend side – probably validate, save into main app database – and then `publish` into Centrifugo using HTTP API so Centrifugo broadcast message to all clients subscribed on channel.

Server API works on `/api` endpoint. It's very simple to use: you just have to send POST request with JSON command to this endpoint.

In this chapter we will look at API protocol internals - for new API client library authors and just if you are curious how existing API clients work.

API request is a POST HTTP request with `application/json` Content-Type and JSON payload in request body.

API protected by `api_key` secret key set in Centrifugo configuration. This API key must be set in request `Authorization` header in this way:

```
Authorization: apikey <KEY>
```

It's possible to disable API key check on Centrifugo side using `api_insecure` configuration option. Be sure to protect API endpoint by firewall rules in this case to prevent anyone in internet to send commands over your unprotected Centrifugo API. API key auth is not very safe for man-in-the-middle so recommended way is running Centrifugo with TLS (we are in 2018 in the end).

Command is a JSON object with two properties: `method` and `params`.

`method` is a name of command you want to call.
`params` is an object with command arguments.

There are several commands available. Let's investigate each of available server API commands.

### publish

Publish command allows to publish data into channel. It looks like this:

```json
{
    "method": "publish",
    "params": {
        "channel": "chat", 
        "data": {
            "text": "hello"
        }
    } 
}
```

Let's apply all information said above and send publish command to Centrifugo. We will send request using `requests` library for Python. 

```python
import json
import requests

command = {
    "method": "publish",
    "params": {
        "channel": "docs", 
        "data": {
            "content": "1"
        }
    }
}

api_key = "YOUR_API_KEY"
data = json.dumps(commands)
headers = {'Content-type': 'application/json', 'Authorization': 'apikey ' + api_key}
resp = requests.post("https://centrifuge.example.com/api", data=encoded_data, headers=headers)
print(resp.json())
```

The same using `httpie` console tool:

```bash
$ echo '{"method": "publish", "params": {"channel": "chat", "data": {"text": "hello"}}}' | http "localhost:8000/api" Authorization:"apikey KEY" -vvv
POST /api HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Authorization: apikey KEY
Connection: keep-alive
Content-Length: 80
Content-Type: application/json
Host: localhost:8000
User-Agent: HTTPie/0.9.8

{
    "method": "publish",
    "params": {
        "channel": "chat",
        "data": {
            "text": "hello"
        }
    }<commit_msg>fix api docs<commit_after># Server HTTP API

HTTP API is a way to send commands to Centrifugo.

Why we need API?

If you look at configuration options you see an option called `publish` defined on configuration top level and for channel namespace. 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 send new event from client to backend over non-Centrifugo transport (for example via AJAX request in web application), then process it on application backend side – probably validate, save into main app database – and then `publish` into Centrifugo using HTTP API so Centrifugo broadcast message to all clients subscribed on channel.

Server API works on `/api` endpoint. It's very simple to use: you just have to send POST request with JSON command to this endpoint.

In this chapter we will look at API protocol internals - for new API client library authors and just if you are curious how existing API clients work.

API request is a POST HTTP request with `application/json` Content-Type and JSON payload in request body.

API protected by `api_key` secret key set in Centrifugo configuration. This API key must be set in request `Authorization` header in this way:

```
Authorization: apikey <KEY>
```

It's possible to disable API key check on Centrifugo side using `api_insecure` configuration option. Be sure to protect API endpoint by firewall rules in this case to prevent anyone in internet to send commands over your unprotected Centrifugo API. API key auth is not very safe for man-in-the-middle so recommended way is running Centrifugo with TLS (we are in 2018 in the end).

Command is a JSON object with two properties: `method` and `params`.

`method` is a name of command you want to call.
`params` is an object with command arguments.

There are several commands available. Let's investigate each of available server API commands.

### publish

Publish command allows to publish data into channel. It looks like this:

```json
{
    "method": "publish",
    "params": {
        "channel": "chat", 
        "data": {
            "text": "hello"
        }
    } 
}
```

Let's apply all information said above and send publish command to Centrifugo. We will send request using `requests` library for Python. 

```python
import json
import requests

command = {
    "method": "publish",
    "params": {
        "channel": "docs", 
        "data": {
            "content": "1"
        }
    }
}

api_key = "YOUR_API_KEY"
data = json.dumps(command)
headers = {'Content-type': 'application/json', 'Authorization': 'apikey ' + api_key}
resp = requests.post("https://centrifuge.example.com/api", data=data, headers=headers)
print(resp.json())
```

The same using `httpie` console tool:

```bash
$ echo '{"method": "publish", "params": {"channel": "chat", "data": {"text": "hello"}}}' | http "localhost:8000/api" Authorization:"apikey KEY" -vvv
POST /api HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Authorization: apikey KEY
Connection: keep-alive
Content-Length: 80
Content-Type: application/json
Host: localhost:8000
User-Agent: HTTPie/0.9.8

{
    "method": "publish",
    "params": {
        "channel": "chat",
        "data": {
            "text": "hello"
        }
    }
{'fraction_non_alphanumeric': 0.08809182209469153, 'fraction_numerical': 0.005738880918220947, 'mean_word_length': 3.8443363446838084, 'pattern_counts': {'":': 40, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1431106', 'n_tokens_mistral': 1908, 'n_tokens_neox': 1823, 'n_words': 924}