1# HTTP REST/Websocket API endpoint 2 3EJDB engine provides the ability to start a separate HTTP/Websocket endpoint worker exposing network API for quering and data modifications. 4 5The easiest way to expose database over the network is using the standalone `jbs` server. (Of course if you plan to avoid `C API` integration). 6 7## jbs server 8 9``` 10jbs -h 11 12EJDB 2.0.0 standalone REST/Websocket server. http://ejdb.org 13 14 --file <> Database file path. Default: db.jb 15 -f <> (same as --file) 16 --port ## HTTP port number listen to. Default: 9191 17 -p ## (same as --port) 18 --bind <> Address server listen. Default: localhost 19 -b <> (same as --bind) 20 --access <> Server access token matched to 'X-Access-Token' HTTP header value 21 -a <> (same as --access) 22 --trunc Cleanup existing database file on open 23 -t (same as --trunc) 24 --wal Use write ahead logging (WAL). Must be set for data durability. 25 -w (same as --wal) 26 27Advanced options 28 --sbz ## Max sorting buffer size. If exceeded, an overflow temp file for data will be created. Default: 16777216, min: 1048576 29 --dsz ## Initial size of buffer to process/store document on queries. Preferable average size of document. Default: 65536, min: 16384 30 --bsz ## Max HTTP/WS API document body size. Default: 67108864, min: 524288 31 32Use any of the following input formats: 33 -arg <value> -arg=<value> -arg<value> 34 35Use the -h, -help or -? to get this information again. 36``` 37 38## HTTP API 39 40Access to HTTP endpoint can be protected by a token specified with `--access` 41command flag or by C API `EJDB_HTTP` options. If access token specified on server, client must provide `X-Access-Token` HTTP header value. If token is required and not provided by client the `401` HTTP code will be reported. If access token is not matched to the token provided the `403` HTTP code will be returned. 42For any other errors server will respond with `500` error code. 43 44## REST API 45 46### POST /{collection} 47Add a new document to the `collection`. 48* `200` success. Body: a new document identifier as `int64` number 49 50### PUT /{collection}/{id} 51Replaces/store document under specific numeric `id` 52* `200` on success. Empty body 53 54### DELETE /{collection}/{id} 55Removes document identified by `id` from a `collection` 56* `200` on success. Empty body 57* `404` if document not found 58 59### PATCH /{collection}/{id} 60Patch a document identified by `id` by [rfc7396](https://tools.ietf.org/html/rfc7396), 61[rfc6902](https://tools.ietf.org/html/rfc6902) data. 62* `200` on success. Empty body 63 64### GET | HEAD /{collections}/{id} 65Retrieve document identified by `id` from a `collection`. 66* `200` on success. Body: JSON document text. 67 * `content-type:application/json` 68 * `content-length:` 69* `404` if document not found 70 71### POST / 72Query a collection by provided query as POST body. 73Body of query should contains collection name in use in the first filter element: `@collection_name/...` 74Request headers: 75* `X-Hints` comma separated extra hints to ejdb2 database engine. 76 * `explain` Show query execution plan before first element in result set separated by `--------------------` line. 77Response: 78* Response data transfered using [HTTP chunked transfer encoding](https://en.wikipedia.org/wiki/Chunked_transfer_encoding) 79* `200` on success. 80* JSON documents separated by `\n` in the following format: 81 ``` 82 \r\n<document id>\t<document JSON body> 83 ... 84 ``` 85 86Example: 87 88``` 89curl -v --data-raw '@family/[age > 18]' -H 'X-Access-Token:myaccess01' http://localhost:9191 90* Rebuilt URL to: http://localhost:9191/ 91* Trying 127.0.0.1... 92* TCP_NODELAY set 93* Connected to localhost (127.0.0.1) port 9191 (#0) 94> POST / HTTP/1.1 95> Host: localhost:9191 96> User-Agent: curl/7.58.0 97> Accept: */* 98> X-Access-Token:myaccess01 99> Content-Length: 18 100> Content-Type: application/x-www-form-urlencoded 101> 102* upload completely sent off: 18 out of 18 bytes 103< HTTP/1.1 200 OK 104< connection:keep-alive 105< content-type:application/json 106< transfer-encoding:chunked 107< 108 1094 {"firstName":"John","lastName":"Ryan","age":39} 1103 {"firstName":"Jack","lastName":"Parker","age":35,"pets":[{"name":"Sonic","kind":"mouse","likes":[]}]} 1111 {"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"}} 112* Connection #0 to host localhost left intact 113``` 114 115``` 116curl --data-raw '@family/[lastName = "Ryan"]' -H 'X-Access-Token:myaccess01' -H 'X-Hints:explain' http://localhost:9191 117[INDEX] MATCHED STR|3 /lastName EXPR1: 'lastName = "Ryan"' INIT: IWKV_CURSOR_EQ 118[INDEX] SELECTED STR|3 /lastName EXPR1: 'lastName = "Ryan"' INIT: IWKV_CURSOR_EQ 119 [COLLECTOR] PLAIN 120-------------------- 1214 {"firstName":"John","lastName":"Ryan","age":39} 122``` 123 124### OPTIONS / 125Fetch ejdb JSON metadata and available HTTP methods in `Allow` response header. 126Example: 127``` 128curl -X OPTIONS -H 'X-Access-Token:myaccess01' http://localhost:9191/ 129{ 130 "version": "2.0.0", 131 "file": "db.jb", 132 "size": 16384, 133 "collections": [ 134 { 135 "name": "family", 136 "dbid": 3, 137 "rnum": 3, 138 "indexes": [ 139 { 140 "ptr": "/lastName", 141 "mode": 4, 142 "idbf": 64, 143 "dbid": 4, 144 "rnum": 3 145 } 146 ] 147 } 148 ] 149} 150``` 151 152## Websocket API 153 154EJDB supports simple text based protocol over HTTP websocket protocol. 155You can use interactive websocket CLI tool [wscat](https://www.npmjs.com/package/@softmotions/wscat) to communicate with server by hands. 156 157### Commands 158 159#### ? 160Will respond with the following help text message: 161``` 162wscat -H 'X-Access-Token:myaccess01' -c http://localhost:9191 163> ? 164< 165<key> info 166<key> get <collection> <id> 167<key> set <collection> <id> <document json> 168<key> add <collection> <document json> 169<key> del <collection> <id> 170<key> patch <collection> <id> <patch json> 171<key> idx <collection> <mode> <path> 172<key> rmi <collection> <mode> <path> 173<key> rmc <collection> 174<key> query <collection> <query> 175<key> explain <collection> <query> 176<key> <query> 177> 178``` 179 180Note 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. 181 182Errors are returned in the following format: 183``` 184<key> ERROR: <error description> 185``` 186 187#### `<key> info` 188Get database metadatas as JSON document. 189 190#### `<key> get <collection> <id>` 191Retrieve document identified by `id` from a `collection`. 192If document is not found `IWKV_ERROR_NOTFOUND` will be returned. 193 194Example: 195``` 196> k get family 3 197< k 3 { 198 "firstName": "Jack", 199 "lastName": "Parker", 200 "age": 35, 201 "pets": [ 202 { 203 "name": "Sonic", 204 "kind": "mouse", 205 "likes": [] 206 } 207 ] 208} 209``` 210If document not found we will get error: 211``` 212> k get family 55 213< k ERROR: Key not found. (IWKV_ERROR_NOTFOUND) 214> 215``` 216 217#### `<key> set <collection> <id> <document json>` 218Replaces/add document under specific numeric `id`. 219`Collection` will be created automatically if not exists. 220 221#### `<key> add <collection> <document json>` 222Add new document to `<collection>` New `id` of document will be generated 223and returned as response. `Collection> will be created automatically if not exists. 224 225Example: 226``` 227> k add mycollection {"foo":"bar"} 228< k 1 229> k add mycollection {"foo":"bar"} 230< k 2 231> 232``` 233 234#### `<key> del <collection> <id>` 235Remove document identified by `id` from the `collection`. 236If document is not found `IWKV_ERROR_NOTFOUND` will be returned. 237 238#### `<key> patch <collection> <id> <patch json>` 239Apply [rfc7396](https://tools.ietf.org/html/rfc7396) or 240[rfc6902](https://tools.ietf.org/html/rfc6902) patch to the document identified by `id`. 241If document is not found `IWKV_ERROR_NOTFOUND` will be returned. 242 243#### `<key> query <collection> <query>` 244Execute query on documents in specified `collection`. 245**Response:** A set of WS messages with document boidies terminated by the last 246message with empty body. 247``` 248> k query family /* | /firstName 249< k 4 {"firstName":"John"} 250< k 3 {"firstName":"Jack"} 251< k 1 {"firstName":"John"} 252< k 253``` 254Note about last message: `<key>` with no body. 255 256#### `<key> explain <collection> <query>` 257Same as `<key> query <collection> <query>` but the first response message will 258be prefixed by `<key> explain` and contains query execution plan. 259 260Example: 261``` 262> k explain family /* | /firstName 263< k explain [INDEX] NO [COLLECTOR] PLAIN 264 265< k 4 {"firstName":"John"} 266< k 3 {"firstName":"Jack"} 267< k 1 {"firstName":"John"} 268< k 269``` 270 271#### <key> <query> 272Execute 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>` 273 274#### `<key> idx <collection> <mode> <path>` 275Ensure index with specified `mode` (bitmask flag) for given json `path` and `collection`. 276Collection will be created if not exists. 277 278Index mode | Description 279--- | --- 280<code>0x01 EJDB_IDX_UNIQUE</code> | Index is unique 281<code>0x04 EJDB_IDX_STR</code> | Index for JSON `string` field value type 282<code>0x08 EJDB_IDX_I64</code> | Index for `8 bytes width` signed integer field values 283<code>0x10 EJDB_IDX_F64</code> | Index for `8 bytes width` signed floating point field values. 284 285##### Example 286Set unique string index `(0x01 & 0x04) = 5` on `/name` JSON field: 287``` 288k idx mycollection 5 /name 289``` 290 291#### `<key> rmi <collection> <mode> <path>` 292Remove index with specified `mode` (bitmask flag) for given json `path` and `collection`. 293Return error if given index not found. 294 295#### `<key> rmc <collection>` 296Remove collection and all of its data. 297Note: If `collection` is not found no errors will be reported. 298 299