Empowering data self-sovereignty
Samaritandb is a decentralized DBMS that aims to give digital users control and soverignty over their data stored across applications on the internet.
- Build a simple document database that allows: ✅
- creation/removal of databases
- creation/update/removal of documents
- High CAP factor ❌
- Distributed networking
- sharding
- replication
- use of decentralized protocols
- Data local is owned by a DID at all times ❌
- Sensitivity to onchain data access changes ❌
- User data collation and viewing ❌
- No censorship ❌
- Permissioned data sharing between applications ❌
For the achievement of goal one, two crates were simply used:
- Rocket: Rocket is used to handle the http networking aspect of the database. The database was inspired by couchDB and is built to be almost completely RESTful. Rocket helps us substantially in achieving this goal.
- Sled: Sled is used as the underlying data-store which handles all data storage and retrieval operations. It is a high performant embedded database that uses a B+ Tree engine.
- Generate an
application DID
onchain here. - Clone this repo
- In the root folder, find the
config.ini
file. This file contains many information that enables the database to be constomized and run properly. Edit it only if you know what you're doing. - Clear the
.data
directory in the root folder, then create a.dbs
folder in thedata
directory. This directory is the default path for disk data storage. - (Optionally) edit the
Rocket.toml
file. This file contains configurations for the http networking aspect of the database e.g the tcp port address. - Initialize the application that controls the database and owns the data. This is done with the
_auth
route. You'll see how to do that below. - Compile and run
- Start making requests
Please note that since this is a RESTful database, most of the request use methods that cant be easily fired on the browser. The curl
utility on your terminal is the most appropriate to use.
-
index:
method
:GET
route
:/
auth
: Nonefunction
: It says hi to the database. Generally used to ensure database is running on specified address.request (example)
:curl -X GET http://127.0.0.1:1509/
response (example)
:200 Ok {"application_did":"","samaritandb":"Hello Explorer","vendor":{"name":"Algorealm, Inc."},"version":"0.1"}
-
initialize application:
-
method
:POST
-
route
:/_auth
-
auth
: None -
function
: This is one of the most important routes. It gives control of the database subsequently and exclusively to the application. If configured, it immediately kicks off synchronization with peers and tries to be up to date. It is crucial for the database to respond to onchain state changes. -
request (example)
:curl -X POST http://127.0.0.1:1509/_auth -H "Content-Type: application/json" \ -d '{ "did": "did:sam:apps:3e7a1f9c4b8083d2cf63b8b1897d02c9f7bc75b0316bdaf", "secret": "apple banana chair dog elephant forest green happy ice jelly kite" }'
-
response (example)
:200 Ok { "ok":true, "secret": "cf63b8b1897d02" }
-
response (error)
:500 InternalServerError: - DID parse error occurs - Failed to write to config file 404 Not Found: - The credentialis provided matched on onchain account 401 Unauthorized: - An application has already been intialized into the database
-
-
create database:
-
method
:PUT
-
route
:/<database_name>
-
auth
: Basic -
function
: This routes creates a database on success. -
request (example)
:curl -X PUT http://<username>:<password>@127.0.0.1:1509/first_database
-
response (example)
:201 Created {"ok":true}
-
response (error)
:500 InternalServerError: - Failed to create database 409 Conflict: - The database already exists
-
-
delete database:
-
method
:DELETE
-
route
:/<database_name>
-
auth
: Basic -
function
: This routes deleted a database on success. -
request (example)
:curl -X DELETE http://<username>:<password>@127.0.0.1:1509/first_database
-
response (example)
:200 Ok {"ok":true}
-
response (error)
:500 InternalServerError: - Failed to delete database 404 Not Found: - The database does not exist on machine
-
-
all databases:
method
:GET
route
:/_all_dbs
auth
: Nonefunction
: This routes returns a list of all the databases.request (example)
:curl -X GET http://127.0.0.1:1509/_all_dbs
response (example)
:200 Ok ["napoleon_history","people","plankton","relay"]
response (error)
:500 InternalServerError: - Failed to return list
-
uuids:
method
:GET
route
:/_uuids?<count>
auth
: Nonefunction
: This routes returns a list of all UUIDs (adviced) to be used as document IDs.request (example)
:curl -X GET http://127.0.0.1:1509/_uuids?count=3
response (example)
:200 Ok ["39727b01-77e1-4825-bbce-1bfecc824b2e","3d4a443f-a6e0-4f84-9268-90e9fc51d175","6b7558a9-4b62-49c6-ba94-a060645e7024"]
-
update database
-
method
:PUT
-
route
:/<database_name>/<document_id>
-
auth
: Basic -
function
: This routes helps to update a document in the database. -
request (example)
:curl -X PUT 'http://<username>:<password>@127.0.0.1:1509/people/0378f893-e48d-4b69-b821-7a3c2ea7b4b1' \ -H "Content-Type: application/json" -H "X-DID: did:sam:root:3e7a1f9c4b8083d2cf63b8b1897d02c9f7bc75b0316bdaf2" \ -d '{"data": { "name":"Victoria Temilade Adekunle", "role_model":"Martin Luther King", "complexion":"fair", "_rev": "1-d3621aab8cbcec74b10202ac75ca98cb"}}'
-
response (example)
:200 Ok {"id": "0378f893-e48d-4b69-b821-7a3c2ea7b4b1", "ok":true, "rev": "2-e4a21aab8cb8fa74b10202ac75ca98cb"}
-
response (error)
:500 InternalServerError: - write operation failed 409 Conflict: - the rev field failed to match - the DID specified in the header does not match the one in memory 404 Not Found: - the database does not exist on machine 400 BadRequest, - invalid or missing X-DID header
-
header
: The X-DID header is used to associate a user DID with the piece of data being stored. If it is absent or incorrect, a 400 error is returned and the data cannot be saved to the database. It is crucial that every piece of data is associated with a valid DID and the DID will also be examined for its existence onchain. If the DID does not exist onchain, the data stored will soon be removed from the database if the previous write was successful. -
revisions
: Revisions are useful to prevent conflict in data update. With the right_rev
field, the database is sure that you're pointing to the latest document and are up to date. This goes a long way in conflict resolution. The_rev
field is not included in the first write request, only subsequently when the database has returned a rev ID on write. This rev ID must then be included in the next request.
-
-
read document
-
method
:GET
-
route
:/<database_name>/<document_id>
-
auth
: Basic -
function
: This routes fetches a document in the database. -
request (example)
:curl -X GET http://<username>:<password>@127.0.0.1:1509/people/0378f893-e48d-4b69-b821-7a3c2ea7b4b1
-
response (example)
:200 Ok { "id":"0378f893-e48d-4b69-b821-7a3c2ea7b4b2", "complexion":"fair", "name":"Victoria Adekunle","role_model":"Martin Luther King", "_rev":"1-5ac8ff0a3c7aa4d4c3a39c316560fa7e" }
-
response (error)
:500 InternalServerError: - read operation failed 404 Not Found: - the document does not exist - the database does not exist
-
-
delete document
-
method
:DELETE
-
route
:/<database_name>/<document_id>
-
auth
: Basic -
function
: This routes deletes a document in the database. -
request (example)
:curl -X DELETE http://<username>:<password>@127.0.0.1:1509/people/0378f893-e48d-4b69-b821-7a3c2ea7b4b1
-
response (example)
:200 Ok { "ok": true }
-
response (error)
:500 InternalServerError: - delete operation failed 404 Not Found: - the database does not exist
-
The basic authentication authenticates the username and password and permits the request to be processed if it passes. The username is gotten from the applications DID. It is the suffix SS58 address to the application DID. The password is the value of the secret
key returned on the /_auth
route during application initialization.
curl -X DELETE http://3e7a1f9c4b8083d2cf63b8b1897d02c9f7bc75b0316bdaf:[email protected]:1509/people/0378f893-e48d-4b69-b821-7a3c2ea7b4b1