Public API
The Raijin database listens on TCP port 2500 for incoming HTTP requests. A GET request will retrieve the built-in web UI.
API query structure
A POST request sent with the following structure will execute a query:
{
"query": "QUERY_STRING"
}
The QUERY_STRING
may contain any number or combination of supported SQL queries (SELECT
, INSERT
, etc.), each terminated with a semicolon (;
), with the entire set of queries enclosed in double quotes (" "
).
Direct JSON ingestion API
A POST request to RAIJIN_SRV:RAIJIN_PORT/DB_NAME/TABLE_NAME
with a series, or an array, of single-object JSON documents will insert data into the specified table.
Both the database identified by DB_NAME
and the table identified by TABLE_NAME
must already exist.
The response indicates the number of records successfully ingested.
{"copy":4}
Malformed POST data will return an HTTP 400 status code. See Error handling for further details.
NDJSON
JSON objects are often saved to file or streamed over the network as NDJSON (newline-delimited JSON). NDJSON data can be POSTed to Rajin as is for ingestion as seen here.
$ curl -sS raijin.example.com:2500/logs/demo -d '{"field1":-3.2,"field2":false}
{"field1":5.671,"field2":true}
{"hostname":"g01c335n2027","os":"Windows","active":1}
{"hostname":"g01c335n2028","os":"Linux","active":0}
'
Array of flat JSON objects
Some applications natively use and output data as JavaScript arrays of JSON objects. Such applications can POST their data directly to Raijin without additional formatting.
$ curl -sS raijin.example.com:2500/logs/demo -d '[{"field1":-3.2,"field2":false},{"field1":5.671,"field2":true},{"hostname":"g01c335n2027","os":"Windows","active":1},{"hostname":"g01c335n2028","os":"Linux","active":0}]'
Querying Raijin
The following examples use the API query structure for querying Raijin.
Database administration
Like most SQL-capable database engines, Raijin accepts standard SQL queries for administering databases and tables.
In this example, a new, schemaless table called demo
is created.
curl -sS raijin.example.com:2500 -d '{"query":"USE logs; CREATE TABLE demo();"}'
$ curl -sS raijin.example.com:2500 -d '{"query":"USE logs; SHOW TABLES;"}'
{"table":"demo","record_count":"14","encrypted":"no","partitioning_type":"none","size":"71 bytes"}
Querying for data
Data queries must reference existing tables and the database they belong to.
If DB_NAME
is not specified in the FROM
clause as FROM DB_NAME.TABLE_NAME
, then the SQL query needs to be prefixed with USE DB_NAME;
.
curl -sS raijin.example.com:2500 -d '{"query":"USE logs; SELECT * FROM demo;"}'
{"_id":4311,"field1":-3.2,"field2":false}
{"_id":4312,"field1":5.671,"field2":true}
{"_id":4313,"hostname":"g01c335n2027","os":"Windows","active":1}
{"_id":4314,"hostname":"g01c335n2028","os":"Linux","active":0}
curl -sS raijin.example.com:2500 -d '{"query":"SELECT * FROM logs.demo;"}'
{"_id":4311,"field1":-3.2,"field2":false}
{"_id":4312,"field1":5.671,"field2":true}
{"_id":4313,"hostname":"g01c335n2027","os":"Windows","active":1}
{"_id":4314,"hostname":"g01c335n2028","os":"Linux","active":0}
For queries that involve only constants or functions, i.e., queries tha do not require a FROM
clause, there is no need to reference a DB_NAME
or TABLE_NAME
.
$ curl -sS raijin.example.com:2500 -d '{"query":"SELECT pi(),ln(2.718281828)"}'
{"pi":3.141593,"ln":1}
curl -sS raijin.example.com:2500 -d '{"query":"SELECT QUARTER(NOW()),YEAR(NOW())"}'
{"quarter":2,"year":2022}
Error handling
Raijin will return a HTTP 400 status code and a JSON-formatted response for invalid SQL statements.
$ curl -sv raijin.example.com:2500 -d '{"query":"selert 1 as one;"}' | jq
* Trying 192.168.1.60:2500...
* Connected to raijin.example.com (192.168.1.60) port 2500 (#0)
> POST / HTTP/1.1
> Host: raijin.example.com:2500
> User-Agent: curl/7.77.0
> Accept: */*
> Content-Length: 28
> Content-Type: application/x-www-form-urlencoded
>
} [28 bytes data]
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request (1)
< Content-Length: 157
< Content-Type: text/html
<
{ [157 bytes data]
* Connection #0 to host raijin.example.com left intact
{
"raijin-exception": {
"parser-location": "http:1:1: ",
"tag_reason": "syntax error at or near \"selert\"", (2)
"where": "scan.cc:9246",
"error_code": "16801924"
}
}
1 | HTTP 400 status code |
2 | tag_reason indicates that SELECT was misspelled as selert . |
The response indicates the number of records successfully ingested.
In case of ingestion errors, the API will respond with HTTP 200
and the number of successfully ingested records.
$ curl -sv raijin.example.com:2500/logs/demo -d '{"field1":-3.2,"field2":false}
> {"field1":5.671,"field2":true}
> {"hostname":"g01c335n2027","os":"Windows",active:1} (1)
> {"hostname":"g01c335n2028","os":"Linux","active":0} (2)
> '
* Trying 192.168.1.60:2500...
* Connected to raijin.example.com (192.168.1.60) port 2500 (#0)
> POST /logs/demo HTTP/1.1
> Host: raijin.example.com:2500
> User-Agent: curl/7.77.0
> Accept: */*
> Content-Length: 166
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK (3)
< Transfer-Encoding: chunked
< Content-Type: text/json
<
{"copy":3} (4)
* Connection #0 to host raijin.example.com left intact
1 | This object violates JSON syntax by not enclosing the active key in double quotes (" " ) and was not ingested. |
2 | This object has valid JSON syntax and was ingested. |
3 | HTTP 200 OK |
4 | This shows that 3 of the 4 records were ingested. |
{"_id":1,"field1":-3.2,"field2":false}
{"_id":2,"field1":5.671,"field2":true}
{"_id":3,"hostname":"g01c335n2028","os":"Linux","active":0}