Getting Started
Start with Docker
Mongo installation:
docker run -d --name mongo6 -p 27017:27017 mongo:6 mongod --replSet rs
# 0fb24fd1422e45efa2d37ea...
Initialize the replicaSet1:
mongo mongodb://localhost:27017/datastore \
--eval 'rs.initiate({"_id":"rs","members":[{"_id":0,"host":"localhost:27017"}]})'
# { "ok" : 1 }
Datastore deployment with administration API up as well as the backoffice (remove this flags in production):
docker run \
-d --name datastore \
--network host \
-e PORT=3001 -e NODE_ENV=development \
-e FEATURE_API_TEMPLATES=true -e FEATURE_API_ADMIN=true \
getanthill/datastore:latest
# 0fb24fd1422e45efa2d37ea...
Check the heartbeat:
curl http://localhost:3001/heartbeat
# {"state":"up"}
The OpenAPI Documentation is available here:
and can be rendered with the Swagger UI with the following link2:
https://petstore.swagger.io/?url=http://localhost:3001/api/api-docs
Creating your first model
Create a simple Event-Source model with:
We are using
jqextensively hereafter. Please install it and support it ❤️!
You can view examples of models with the following command:
curl http://localhost:3001/api/templates/examples/users.json | jq
# {
# "db": "datastore",
# "name": "users",
# "correlation_field": "user_id",
# "schema": {
# "model": {
# "additionalProperties": true,
# "properties": {
# "firstname": {
# "type": "string"
# }
# }
# },
# "events": {
# "CREATED": {
# "0_0_0": {
# "properties": {
# "firstname": {
# "type": "string"
# }
# }
# }
# }
# }
# }
# }
You can then pipe the files available as examples to the model creation request:
curl http://localhost:3001/api/templates/examples/users.json | \
curl -X POST 'http://localhost:3001/api/admin' \
-H 'Authorization: token' \
-H 'Content-Type: application/json' \
-d @- | jq
# {
# "db": "datastore",
# "name": "users",
# "correlation_field": "user_id",
# "created_at": "2020-11-28T17:48:40.236Z",
# "updated_at": "2020-11-28T17:48:40.236Z",
# "version": 0,
# "model_id": "5fc28d781f139c00120935aa",
# ...
# }
Great, let's check that everything is right now and that we are able to create new users!
The following command will check that the datastore correctly took into account your new model
curl -X GET 'http://localhost:3001/api/admin' \
-H 'Authorization: token' \
-H 'Content-Type: application/json' | \
jq '{name: .users.name}'
# {
# "name": "users"
# }
Requesting the API
Let's start creating a user Alice:
curl -X POST 'http://localhost:3001/api/users' \
-H 'Authorization: token' \
-H 'Content-Type: application/json' \
-d '{
"firstname": "Alice"
}' | jq
# {
# "created_at": "2021-10-28T17:57:45.812Z",
# "firstname": "Alice",
# "updated_at": "2021-10-28T17:57:45.812Z",
# "version": 0,
# "user_id": "617ae499f4b53601ade4a164"
# }
You now have an entity called Alice with version=0!
You can retrieve the exact same document with the following request:
curl -X GET 'http://localhost:3001/api/users/617ae499f4b53601ade4a164' \
-H 'Authorization: token' \
-H 'Content-Type: application/json' | jq
# {
# "created_at": "2021-10-28T17:57:45.812Z",
# "firstname": "Alice",
# "updated_at": "2021-10-28T17:57:45.812Z",
# "version": 0,
# "user_id": "617ae499f4b53601ade4a164"
# }
Keep in mind that the user_id 617ae499f4b53601ade4a164
value will change during your own execution!
We can also try to find Alice with:
curl -X GET 'http://localhost:3001/api/users?firstname=Alice' \
-H 'Authorization: token' \
-H 'Content-Type: application/json' | jq
# [
# {
# "created_at": "2021-10-28T17:57:45.812Z",
# "firstname": "Alice",
# "updated_at": "2021-10-28T17:57:45.812Z",
# "version": 0,
# "user_id": "617ae499f4b53601ade4a164"
# }
# ]
Changing the firstname of Alice to Alizz would be
performed with another POST request like so:
curl -X POST 'http://localhost:3001/api/users/617ae499f4b53601ade4a164' \
-H 'Authorization: token' \
-H 'Content-Type: application/json' \
-d '{
"firstname": "Alizz"
}' | jq
# {
# "created_at": "2021-10-28T17:57:45.812Z",
# "firstname": "Alizz",
# "updated_at": "2021-10-28T18:04:11.449Z",
# "version": 1,
# "user_id": "617ae499f4b53601ade4a164"
# }
Did you notice the change on the value of version? This
is now that you will discover the power of
Event-Sourcing!
Let's find the events associated to Alice:
curl -X GET 'http://localhost:3001/api/users/617ae499f4b53601ade4a164/events' \
-H 'Authorization: token' \
-H 'Content-Type: application/json' | jq
# [
# {
# "_id": "617ae499f4b53601ade4a165",
# "created_at": "2021-10-28T17:57:45.812Z",
# "type": "CREATED",
# "v": "0_0_0",
# "firstname": "Alice",
# "version": 0,
# "user_id": "617ae499f4b53601ade4a164"
# },
# {
# "_id": "617ae61bf4b53601ade4a166",
# "created_at": "2021-10-28T18:04:11.449Z",
# "type": "UPDATED",
# "v": "0_0_0",
# "firstname": "Alizz",
# "version": 1,
# "user_id": "617ae499f4b53601ade4a164"
# }
# ]
We see that 2 events have been stored in the database:
1 for the creation, 1 for the firstname update.
Let's say that we changed our mind and we want now to
restore Alice instead of Alizz. We can do that with
the restoration route:
curl -X POST 'http://localhost:3001/api/users/617ae499f4b53601ade4a164/0/restore' \
-H 'Authorization: token' \
-H 'Content-Type: application/json' | jq
# {
# "created_at": "2021-10-28T17:57:45.812Z",
# "firstname": "Alice",
# "updated_at": "2021-10-28T18:11:37.325Z",
# "version": 2,
# "user_id": "617ae499f4b53601ade4a164"
# }
We are now at version=2. And the firstname has been
restored to Alice! And you can do that every model you
are managing with the datastore.
Clean
Now that your tried with success the datastore, you can
clean everything with the following commmands:
docker stop datastore mongo6
docker rm datastore mongo6
docker rmi getanthill/datastore:latest mongo:6
- Required for streaming but not mandatory if you do not use that feature↩
- Might require the installation and activation of the chrome extension Allow CORS: Access-Control-Allow-Origin↩