0.8.0 • Published 3 years ago

flexnes v0.8.0

Weekly downloads
-
License
ISC
Repository
github
Last release
3 years ago

Table of contents

Flexnes

Flexnes (flexible network store) is a database engine for modern web apps and middle-tier backend services. It's built with Google's LevelDB, gRPC and Node.js. Flexnes is also used as an open core in the Serverless SaaS codehooks.io.

Flexnes supports query languages like NoSql (Mongodb like) and Key-Value (Redis like), which makes it a good candidate for persitence storage in your JAMStack, middle-tier and micro-service programming.

Flexnes implements two main APIs:

  • Clean REST API for all-purpouse programming
  • Low level gRPC API for high performance and real time computing.

This repository har two main parts:

  • The Datastore engine source code: ./src/dbengine
  • The REST API HTTP server source code: ./src/restapi.

Getting started

Requirements: Docker and docker-compose.

Start the server using the pre-built official Docker images

# start Flexnes server and REST API server
docker-compose -f official.yml up -d

For local development and changes to the source code: install all packages locally and start the server using the node.js and npm

# clone repo first for local development
git clone https://github.com/RestDB/flexnes.git
cd flexnes
# install dependencies
npm install
# generate development certs
npm run cert
# start REST API server and gRPC server
npm run flexnes

CRUD examples

Add some data with curl

curl --location --request POST 'http://127.0.0.1:3000/dev/data/mycoll' \
--header 'x-apikey: daejoo' \
--header 'Content-Type: application/json' \
--data-raw '{
    "hello": "world!"
}'

# output example
{"hello":"world!","_id":"60ec427298586b1e00000001"}

Get some data with curl

curl --location -g --request GET 'http://127.0.0.1:3000/dev/data/mycoll' \
-G -d 'q={"hello":{"$eq":"world!"}}' \
--header 'x-apikey: daejoo' \
--header 'Content-Type: application/json'

# output example (always array of data from a query)
[{"hello":"world!","_id":"60e86150c9e5731800000001"}]

Update some new data

curl --location --request PUT 'http://127.0.0.1:3000/dev/data/mycoll/60ee9924359a3d1800000001' \
--header 'x-apikey: daejoo' \
--header 'Content-Type: application/json' \
--data-raw '{
    "hello": "universe!"
}'

Delete some data

curl --location --request DELETE 'http://127.0.0.1:3000/dev/data/mycoll/60ee9924359a3d1800000001' \
--header 'x-apikey: daejoo' \
--header 'Content-Type: application/json' \
--data-raw '{
    "hello": "universe!"
}'

Stop the server

docker-compose -f official.yml down

Build and run the server as Docker containers

# build all docker images
docker-compose build

# start Flexnes server and REST API server
docker-compose up -d

# check logs
docker-compose logs -f

# stop all servers
docker-compose down

Flexnes test suite for local testing

Run these if you modify the source code. The Mocha test suite has 54 unit tests and they are located here: src/dbengine/test/test.js.

To run the tests Node.js is required.

# install packages
npm install

# run tests
npm run test-server

A succesfull test run should show the a similar output:

 Flexnes datastore engine tests
    ✓ should connect to server
    ✓ should drop a collection
    ✓ should drop huge collection
    ✓ should create test collections and data
    ...
    ✓ should restore database


  56 passing (13s)

REST API example server

Flexnes comes with a simple Node express REST API server. The following APIs are avaliable.

NoSql API quick overview

URL:

HTTP VERB /{datastore}/data/{collection}?[query params]

VerbRouteDescrption
POST/{datastore}/data/{collection}Create new object(s) as singles or multiple as arrays
PUT/{datastore}/data/{collection}/{id}, {query}Update object(s) by ID or by query
PATCH/{datastore}/data/{collection}/{id}, {query}Update object(s) patch by ID or by query
GET/{datastore}/data/{collection}/{id}, {query}, {hint}Retrieve object(s) by ID or by query
DELETE/{datastore}/data/{collection}/{id}, {query}Delete object(s) by ID or by query

NoSql Query language

Flexnes uses Mongodb query language as implemented by Sift.

E.g.

GET http://localhost:3000/dev/data/places?q={ $in: ["Costa Rica", "Brazil"] }

Key-value API quick overview

All API calls to the key-value Datastore are done as POST with a payload body that describes the command.

URL:

POST /{datastore}/kvdata

Command (body)Description
{"set": {key,val}, opt}Set a key-value pair
{"get": {key}, opt}Get a key-value pair
{"del": {key}, opt}Delete a key
{"incr": {key,val}, opt}Increment a value
{"decr": {key,val}, opt}Decrement value
{"batch": [...], opt}Run multiple commands

E.g.

POST http://localhost:3000/dev/kvdata

{
    "set": {"key": "temp", "value": "hotter"},
    "opt": {"ttl": 60000}
}

Security

The REST API server comes with a simple config file that provides the various API tokens for accessing different data stores. The default config file is located here: ./src/restapi/config.json. Override the config by mouting /www/restapi/config.json to local file you provide.

E.g. the example config.json file located in the root folder lists two API tokens, one for the dev data store and another for the test data store.

{
    "apikeys": {
        "dev": {
            "tjobing": "only for development"
        },
        "test": {
            "pwd123": "only for testing"
        }
    },
    "ip-whitelist": {
        "127.0.0.1": "localhost"
    }
}

Standalone gRPC Datastore server

For high performance applications it is possible to run Flexnes as a gRPC server only, exposing the Protobuf API via gRPC. This allows for any programming language that supports the gRPC protocol to communicate with the Datastore server.

The gRPC API is shown below. You will find the code under src/dbengine/protos/fxs.proto

// The Flexnes service definition.
service Fxs {
  // session
  rpc login (LoginRequest) returns (Response) {}
  
  // nosql db api
  rpc save (SaveRequest) returns (Response) {}
  rpc get (QueryRequest) returns (stream Response) {}
  rpc ensureIndex (IndexRequest) returns (stream Response) {}
  rpc rebuildIndex (IndexRequest) returns (Response) {}
  rpc removeIndex (IndexRequest) returns (Response) {}
  rpc count (CountRequest) returns (Response) {}
  rpc update (UpdateRequest) returns (Response) {}
  rpc dropCollection (DropCollectionRequest) returns (Response) {}
  rpc delete (DeleteRequest) returns (Response) {}
  rpc getKeys (KeysRequest) returns (stream Response) {}
  rpc getValues (ValuesRequest) returns (stream Response) {}
  
  // kv db api
  rpc kvset(KVSetRequest) returns (Response) {}
  rpc kvget(KVGetRequest) returns (Response) {}
  rpc kvdelete(KVDeleteRequest) returns (Response) {}
  rpc kvgetall(KVGetRequest) returns (stream Response) {}
  rpc kvdeleteall(KVDeleteRequest) returns (Response) {}
  rpc kvincr(KVIncrRequest) returns (Response) {}
  rpc kvdecr(KVIncrRequest) returns (Response) {}
  rpc getChangelog(ChangelogRequest) returns (stream Response) {}
  
  // backup restore api
  rpc backup(Empty) returns (stream BackupRequest) {}
  rpc restore(stream BackupRequest) returns (Response) {}
  
  // utility api
  rpc ping(Empty) returns (stream Response){}
  rpc realtime(RealTimeRequest) returns (stream Response){}
  rpc getDBSize(Empty) returns (Response){}
  rpc createDatabase(CreateDatabaseRequest) returns (Response){}
}

Start the gRPC server

Starts the server at the default port 50051

docker-compose -f flexnes-dev.yml up

Example Javascript HTTP client

...

Example Node.js gRPC client

...

0.8.0

3 years ago

0.7.0

3 years ago

0.6.1

3 years ago

0.5.0

3 years ago

0.4.0

3 years ago

0.6.0

3 years ago

0.3.0

3 years ago

0.2.0

3 years ago

0.1.0

3 years ago

0.1.1

3 years ago

0.0.1

3 years ago