REST API

All the functionality of the Brain4it servers is exposed through a simple HTTP REST API. This allows third-party applications developed with other programming languages to interact remotely with a brain to read and write data, invoke a function or manage its modules.

The data format that this API accepts by default is BPL (Brain4it Programming Language), but the POST method also supports JSON and XML formats.

Security model

The modules of a Brain4it server are usually protected with an access key. This access key is set with a special variable named access-key in the global scope of the module.

At server level there is also a general access key defined in a configuration file, that allows to perform any operation on any of its modules.

To invoke a method of the REST API, will be necessary, in most cases, to provide the access key of the module or the server through the Access-Key property in the HTTP header:

PUT /geopos/elements/car23/coordinates HTTP/1.1
Host: localhost:9999
Access-Key: 82769323097141012423
Content-Type: text/plain; charset=utf-8
Content-Length: 11

(23.8 89.9)

In production environments it is strongly recommended to configure the server for accepting http secure connections (https:) to avoid compromising the access key.

URL format

The URL format for all the operations of the REST API is the following: http://<host>:<port>/<base_path>/<module>/<module_path>
where:

When multi-tenant mode is enabled the URL format for all operations also includes the tenant name: http://<host>:<port>/<base_path>/<tenant>/<module>/<module_path>

API summary

List modules

List modules

When the HTTP url points to the modules root (that is module and module_path are not specified), the GET method returns a BPL list describing all the modules that are contained in the server. In this case, no access key is required.

Example:

http://localhost:9999
GET / HTTP/1.1
Host: localhost:9999
HTTP/1.1 200 OK
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers: server-time
Content-Length:95
Content-Type:text/plain;charset=UTF-8
Date:Sat, 04 Nov 2017 19:35:56 GMT
Server-Time: 1509820536367
Server:Brain4it

(("air1" ("icon" => "air" "description" => "Air conditioner 1")) "biometric" "lights" "main")

The returned list may contain for each module:

The descriptive properties of a module are hold in the special variable module-metadata of the module.

Read module data

Read module data

When the HTTP url references a module, the GET method will return the data associated to the module_path.

The access key of the module or the server is required for this operation except when module_path is module-metadata.

Example:

http://localhost:9999/geopos/car23/coordinates
GET /geopos/elements/car23/coordinates HTTP/1.1
Host: localhost:9999
Access-Key: 82769323097141012423
HTTP/1.1 200 OK
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers: server-time
Content-Length:11
Content-Type:text/plain;charset=UTF-8
Date:Sat, 04 Nov 2017 19:35:36 GMT
Server-Time: 1509820536367
Server:Brain4it

(23.8 89.9)

If module_path is omitted, all module data (the global scope) will be returned as a BPL list.

A error will be returned if module or module_path are invalid.

Create module

Create module

The creation of a new module in the server, can be done through a HTTP PUT request indicating the module name to create in the url. The module_path and the HTTP body must be empty. The server access key is required in this case.

Example:

http://localhost:9999/facility
PUT /facility HTTP/1.1
Host: localhost:9999
Access-Key: 553454422234345345
Content-Length:0
HTTP/1.1 200 OK
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers: server-time
Content-Length:26
Content-Type:text/plain;charset=UTF-8
Date:Sat, 04 Nov 2017 19:35:36 GMT
Server-Time: 1509820536367
Server:Brain4it

"Module facility created."

If the operation is successful, the server will return a string indicating that the module was created.

A error will be returned if already exists a module with the same name.

Write module data

Write module data

Module data can be changed with a HTTP PUT request indicating in the url the module and the module_path of the data to update. The HTTP body must contain data (can not be 0 length) in BPL format. The access key of the module or the server is required in this case.

Example:

http://localhost:9999/facility/space012/info
PUT /facility/space012/info HTTP/1.1
Host: localhost:9999
Access-Key: 82769323097141012423
Content-Length:52
Content-Type:text/plain;charset=UTF-8

("description" => "Mayor's room" "surface" => 21.2)
HTTP/1.1 200 OK
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers: server-time
Content-Length:4
Content-Type:text/plain;charset=UTF-8
Date:Sun, 05 Nov 2017 19:35:36 GMT
Server-Time: 1509820536367
Server:Brain4it

null

The server returns the previous data associated with the given module_path.

If module_path is omitted, all module data (the global scope) will be replaced by the given HTTP body.

A error will be returned if module or module_path are invalid.

Destroy module

Destroy module

A server module can be destroyed through a HTTP DELETE request indicating in the url the module to destroy. The module_path must not be specified. This operation requires the access key of the module or the server.

Example:

http://localhost:9999/facility
DELETE /facility HTTP/1.1
Host: localhost:9999
Access-Key: 82769323097141012423
HTTP/1.1 200 OK
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers: server-time
Content-Length:29
Content-Type:text/plain;charset=UTF-8
Date:Sun, 05 Nov 2017 19:35:36 GMT
Server-Time: 1509820536367
Server:Brain4it

"Module facility destroyed."

If the operation is successful, the server will return a string indicating that the module was destroyed.

Delete module data

Delete module data

Module data can be deleted through a HTTP DELETE request indicating in the url the module and module_path of the data to delete. The access key of the module or the server is required in this case.

Example:

http://localhost:9999/facility/space012/info
DELETE /facility/space012/info HTTP/1.1
Host: localhost:9999
Access-Key: 82769323097141012423
HTTP/1.1 200 OK
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers: server-time
Content-Length:52
Content-Type:text/plain;charset=UTF-8
Date:Sun, 05 Nov 2017 19:35:36 GMT
Server-Time: 1509820536367
Server:Brain4it

("description" => "Mayor's room" "surface" => 21.2)

The server returns the data that was associated with the given module_path.

Execute code

Execute code

A BPL expression (or code frament) can be evaluated through a HTTP POST request passing that expression in the HTTP body and providing in the url the module in which to do the evaluation. The module_path must not be specified. This operation requires the access key of the module or the server.

Example:

http://localhost:9999/facility
POST /facility HTTP/1.1
Host: localhost:9999
Access-Key: 82769323097141012423
Content-Length:22
Content-Type:text/plain;charset=UTF-8

(set counter (+ 2 3))
HTTP/1.1 200 OK
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers: server-time
Content-Length:1
Content-Type:text/plain;charset=UTF-8
Date:Sun, 05 Nov 2017 19:35:36 GMT
Server-Time: 1509820536367
Server:Brain4it

5

The server returns the result of evaluating the given code or expression.

Call exterior function

Call exterior function

Exterior functions are user defined functions specially designed to be invoked from external applications through the REST API. These functions are easily recognizable because their name always starts with the at symbol (@). They take two parameters: context and body.

Example:

(set @sum-data
  (function (context body)
    (eval (append (list +) (parse body "json")))
  )
)

An exterior function can be invoked with a HTTP POST request specifying in the url the module (module) and the name (module_path) of the function.

The HTTP body may contain the data to be passed to the exterior function as the body argument. That body can be expressed in BPL, JSON or XML formats in accordance with the Content-Type header property. When the Content-Type is text/plain body will be converted to a BPL object. In the other cases, body will be passed to the function as a string.

The context argument is a BPL list that contains the following information:

The result of the function will be sent to the external invoking application. The format in which that result will be sent is determined by the property content-type of response-headers. By default, the result will be encoded as a BPL object.

It is not required to provide the access key when invoking exterior functions. That does not always means that exterior functions are unprotected because they may implement other security strategies.

Example:

http://localhost:9999/facility/@sum-data
POST /facility/@sum-data HTTP/1.1
Host: localhost:9999
Access-Key: 82769323097141012423
Content-Type: application/json
Content-Length: 10

[8, 5, 3]
HTTP/1.1 200 OK
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers: server-time
Content-Length:5
Content-Type:text/plain;charset=UTF-8
Date:Sat, 04 Nov 2017 19:35:36 GMT
Server-Time: 1509820536367
Server:Brain4it

16

The server will return the result of evaluating the exterior function.

Watch exterior function

Watch exterior functions

The widgets of a dashboard need to call the exterior functions of a module to show information to the user. These functions could be invoked doing HTTP requests to the server at a certain frequency (polling), but when the function values vary very often, this method has many drawbacks.

That's why the Brain4it servers offer a more efficient way to monitor the value returned by exterior functions based on a technique similiar to streaming: the HTTP connection will remain open and whenever the value returned by a function changes, the server will send that value to the client through the connection using the standard HTTP chunked transfer encoding.

Exterior functions can be monitored doing a HTTP POST request specifying in the url the module where they are defined and providing in the HTTP body the BPL list that contains the names of the exterior functions to watch.

A special HTTP header property called Monitor must be specified to inform that this is a monitoring request. The value of this header property is the interval, in milliseconds, at which the server will evaluate the given exterior functions. When this value is 0, the server will only evaluate a function if it receives a change notification for that function. (See the module-notify function for more details).

It is not required to provide the access key for this operation.

Example:

http://localhost:9999/facility
POST /facility HTTP/1.1
Host: localhost:9999
Monitor: 1000
Content-Type:text/plain; charset=utf-8
Content-Length:34

("@get-photo" "@display" "@light-level")
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Date:Sat, 04 Nov 2017 19:39:56 GMT
Server: Brain4it
Transfer-Encoding: chunked

27
"1d01e78e-212e-4fe7-bb1d-d28312c4645e"

21
("@get-value" "A" 1535183881242)

23
("@light-level" 423 1509820797274)

22
("@display" "OPEN" 1509820796556)

1


23
("@light-level" 420 1509820799234)

1


The first chunk sent by the server is the monitoring session identifier, a quoted string that will be used later in an unwatch request to finish the monitoring session.

The data chunks that follows are BPL lists with three elements: the function name, the new value returned by the function and the server time (in milliseconds) when that value was sent.

All chunks are ended by a LF (line feed) character followed by a CR+LF that mandates the chuncked protocol.

The server will continue sending data until the client close the connection or an unwatch request is received.

When none of the monitored functions change for a period greater than 30 seconds (monitorPingTime server parameter) a LF (line feed) character is sent (as a ping message) to check if the connection has been closed.

Unwatch exterior function

Unwatch exterior functions

An application that has an active monitoring session can inform the server that it is no longer interested in receiving data with an unwatch request. These requests are identical to watch requests but instead of a list of exterior functions, its body must contain the monitoring session identifier obtained in the previous watch request.

POST /facility HTTP/1.1
Host: localhost:9999
Monitor: 1000
Content-Type:text/plain; charset=utf-8
Content-Length:39

"1d01e78e-212e-4fe7-bb1d-d28312c4645e"
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Date:Sat, 04 Nov 2017 19:39:59 GMT
Server: Brain4it
Content-Type:text/plain; charset=utf-8
Content-Length:11

"unwatched"
Top