Skip to main content

Database API

So far, all the queries and mutations that have been discussed were specific to the stored and managed developer or user-created objects. However, that is only one aspect of DefraDB's GraphQL API. The other part of DefraDB GraphQL API is the auxiliary APIs, which include MerkleCRDT Traversal, Schema Management, and more.

MerkleCRDTs

All objects in DefraDB are stored in MerkleCRDTs (see Merkle CRDT Guide). These MerkleCRDTs are represented as a series of small updates connected in a MerkleDAG. The MerkleDAG is a Merklized version of a DAG (Directed Acyclical Graph), which means that each node in the DAG references a parent node through some kind of Content Identifier (CID).

The image below shows an example structure of a MerkleDAG.

The Head CID represents the "current" or "latest" state of a MerkleDAG.

DefraDB allows you to query, traverse, and validate the DAG structure, allowing for self-verifying data structures.

In DefraDB Database API, DAG nodes are represented as Commit, CommitLink, and Delta types. They are defined as shown below:

# Commit is an individual node in a CRDTs MerkleDAG
type Commit {
cid: String // cid is the Content Identifier of this commit
height: Int // height is the incremental version of the current commit
delta: Delta // delta is the delta-state update generated by a CRDT mutation
previous: [Commit] // previous is the links to the previous node in the MerkleDAG
links: [CommitLink] // links are any additional commits this commit may reference.
}

# CommitLink is a named link to a commit
type CommitLink {
name: String // name is the name of the CommitLink
commit: Commit // commit is the linked commit
}

# Delta is the differential state change from one node to another
type Delta {
payload: String // payload is a base64 encoded byte-array.
}

To query the latest commit of an object (with id: '123'):

query {
latestCommits(docid: "123") {
cid
height
delta {
payload
}
}
}

To query all the commits of an object (with id: '123'):

query {
allCommits(docid: "123") {
cid
height
delta {
payload
}
}
}

To query a specific commit:

query {
Commits(cid: 'Qm123') {
cid
height
delta {
payload
}
}
}

In addition to using Commits specific queries, include commit version sub-fields in object queries.

query {
User {
_key
name
age

_version {
cid
height
}
}
}

The above example shows how to query for the additional _version field that is generated automatically for each added schema type. The _version has the same execution as latestCommits.

Both _version and latestCommits return an array of Commits types because the HEAD of the MerkleDAG can point to more than one DAG node. This is caused by two concurrent updates to the DAG at the same height. The DAG usually has a single head. However, it can also have multiple heads.

Commits queries also work with aggregates, grouping, limit, offset, order, dockey, cid, and depth There is __typename introspection keyword that works on all queries that does not appear to be documented anywhere, for example:

commits(dockey: "bae-52b9170d-b77a-5887-b877-cbdbb99b009f") {
cid
__typename
}