EJDB engine provides the ability to start a separate HTTP/Websocket endpoint worker exposing network API for quering and data modifications.
SSL (TLS 1.2) is supported by jbs
server.
The easiest way to expose database over the network is use the standalone jbs
server. (Of course if you want to avoid C API
integration).
Usage:
./jbs [options]
-v, --version Print program version.
-f, --file=<> Database file path. Default: ejdb2.db
-p, --port=NUM HTTP server port numer. Default: 9191
-l, --listen=<> Network address server will listen. Default: localhost
-k, --key=<> PEM private key file for TLS 1.2 HTTP server.
-c, --certs=<> PEM certificates file for TLS 1.2 HTTP server.
-a, --access=TOKEN|@FILE Access token to match 'X-Access-Token' HTTP header value.
-r, --access-read Allows unrestricted read-only data access.
-C, --cors Enable COSR response headers for HTTP server
-t, --trunc Cleanup/reset database file on open.
-w, --wal use the write ahead log (WAL). Used to provide data durability.
Advanced options:
-S, --sbz=NUM Max sorting buffer size. If exceeded, an overflow temp file for data will be created.
Default: 16777216, min: 1048576
-D, --dsz=NUM Initial size of buffer to process/store document on queries. Preferable average size of document.
Default: 65536, min: 16384
-T, --trylock Exit with error if database is locked by another process.
If not set, current process will wait for lock release.
HTTP endpoint may be protected by a token specified with --access
flag or C API EJDB_HTTP
struct.
If access token was set, client should provide X-Access-Token
HTTP header.
If token is required but not provided by client 401
HTTP code will be reported.
If access token is not matched to the token provided by client server will respond with 403
HTTP code.
Add a new document to the collection
.
200
success. Body: a new document identifier asint64
number
Replaces/store document under specific numeric id
200
on success. Empty body
Removes document identified by id
from a collection
200
on success. Empty body404
document not found
Patch a document identified by id
by rfc7396,
rfc6902 data.
200
on success. Empty body
Retrieve document identified by id
from a collection
.
200
on success. Body: JSON document text.content-type:application/json
content-length:
404
document not found
Query a collection by provided query as POST body.
Body of query should contains collection name in use in the first filter element: @collection_name/...
Request headers:
X-Hints
comma separated extra hints to ejdb2 database engine.explain
Show query execution plan before first element in result set separated by--------------------
line. Response:
- Response data transfered using HTTP chunked transfer encoding
200
on success.- JSON documents separated by
\n
in the following format:\r\n<document id>\t<document JSON body> ...
Example:
curl -v --data-raw '@family/[age > 18]' -H 'X-Access-Token:myaccess01' http://localhost:9191
* Rebuilt URL to: http://localhost:9191/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 9191 (#0)
> POST / HTTP/1.1
> Host: localhost:9191
> User-Agent: curl/7.58.0
> Accept: */*
> X-Access-Token:myaccess01
> Content-Length: 18
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 18 out of 18 bytes
< HTTP/1.1 200 OK
< connection:keep-alive
< content-type:application/json
< transfer-encoding:chunked
<
4 {"firstName":"John","lastName":"Ryan","age":39}
3 {"firstName":"Jack","lastName":"Parker","age":35,"pets":[{"name":"Sonic","kind":"mouse","likes":[]}]}
1 {"firstName":"John","lastName":"Doe","age":28,"pets":[{"name":"Rexy rex","kind":"dog","likes":["bones","jumping","toys"]},{"name":"Grenny","kind":"parrot","likes":["green color","night","toys"]}],"address":{"city":"New York","street":"Fifth Avenue"}}
* Connection #0 to host localhost left intact
curl --data-raw '@family/[lastName = "Ryan"]' -H 'X-Access-Token:myaccess01' -H 'X-Hints:explain' http://localhost:9191
[INDEX] MATCHED STR|3 /lastName EXPR1: 'lastName = "Ryan"' INIT: IWKV_CURSOR_EQ
[INDEX] SELECTED STR|3 /lastName EXPR1: 'lastName = "Ryan"' INIT: IWKV_CURSOR_EQ
[COLLECTOR] PLAIN
--------------------
4 {"firstName":"John","lastName":"Ryan","age":39}
Fetch ejdb JSON metadata and available HTTP methods in Allow
response header.
Example:
curl -X OPTIONS -H 'X-Access-Token:myaccess01' http://localhost:9191/
{
"version": "2.0.0",
"file": "db.jb",
"size": 16384,
"collections": [
{
"name": "family",
"dbid": 3,
"rnum": 3,
"indexes": [
{
"ptr": "/lastName",
"mode": 4,
"idbf": 64,
"dbid": 4,
"rnum": 3
}
]
}
]
}
EJDB supports simple text based protocol over HTTP websocket protocol. You can use interactive websocket CLI tool wscat to communicate with server by hands.
Will respond with the following help text message:
wscat -H 'X-Access-Token:myaccess01' -c http://localhost:9191
> ?
<
<key> info
<key> get <collection> <id>
<key> set <collection> <id> <document json>
<key> add <collection> <document json>
<key> del <collection> <id>
<key> patch <collection> <id> <patch json>
<key> idx <collection> <mode> <path>
<key> rmi <collection> <mode> <path>
<key> rmc <collection>
<key> query <collection> <query>
<key> explain <collection> <query>
<key> <query>
>
Note about <key>
prefix before every command; It is an arbitrary key chosen by client and designated to identify particular websocket request, this key will be returned with response to request and allows client to identify that response for his particular request.
Errors are returned in the following format:
<key> ERROR: <error description>
Get database metadatas as JSON document.
Retrieve document identified by id
from a collection
.
If document is not found IWKV_ERROR_NOTFOUND
will be returned.
Example:
> k get family 3
< k 3 {
"firstName": "Jack",
"lastName": "Parker",
"age": 35,
"pets": [
{
"name": "Sonic",
"kind": "mouse",
"likes": []
}
]
}
If document not found we will get error:
> k get family 55
< k ERROR: Key not found. (IWKV_ERROR_NOTFOUND)
>
Replaces/add document under specific numeric id
.
Collection
will be created automatically if not exists.
Add new document to <collection>
New id
of document will be generated
and returned as response. `Collection> will be created automatically if not exists.
Example:
> k add mycollection {"foo":"bar"}
< k 1
> k add mycollection {"foo":"bar"}
< k 2
>
Remove document identified by id
from the collection
.
If document is not found IWKV_ERROR_NOTFOUND
will be returned.
Apply rfc7396 or
rfc6902 patch to the document identified by id
.
If document is not found IWKV_ERROR_NOTFOUND
will be returned.
Execute query on documents in specified collection
.
Response: A set of WS messages with document boidies terminated by the last
message with empty body.
> k query family /* | /firstName
< k 4 {"firstName":"John"}
< k 3 {"firstName":"Jack"}
< k 1 {"firstName":"John"}
< k
Note about last message: <key>
with no body.
Same as <key> query <collection> <query>
but the first response message will
be prefixed by <key> explain
and contains query execution plan.
Example:
> k explain family /* | /firstName
< k explain [INDEX] NO [COLLECTOR] PLAIN
< k 4 {"firstName":"John"}
< k 3 {"firstName":"Jack"}
< k 1 {"firstName":"John"}
< k
Execute query text. Body of query should contains collection name in use in the first filter element: @collection_name/...
. Behavior is the same as for: <key> query <collection> <query>
Ensure index with specified mode
(bitmask flag) for given json path
and collection
.
Collection will be created if not exists.
Index mode | Description |
---|---|
0x01 EJDB_IDX_UNIQUE |
Index is unique |
0x04 EJDB_IDX_STR |
Index for JSON string field value type |
0x08 EJDB_IDX_I64 |
Index for 8 bytes width signed integer field values |
0x10 EJDB_IDX_F64 |
Index for 8 bytes width signed floating point field values. |
Set unique string index (0x01 & 0x04) = 5
on /name
JSON field:
k idx mycollection 5 /name
Remove index with specified mode
(bitmask flag) for given json path
and collection
.
Return error if given index not found.
Remove collection and all of its data.
Note: If collection
is not found no errors will be reported.