offline-web/DESIGN.md

121 lines
3.2 KiB
Markdown

# Design Notes
## Synchronization
We assume that our resources map easily to REST concepts.
- Resources map to a path.
- Groups of resources are represented in the path structure.
- `HEAD` to get the header to check whether we need to sync.
- `POST` is create
- `PUT` is mutate
- `GET` retrieves the resource
- `DELETE` removes the resources
## Resource Query Datamodel
We assume all resources are content-addressable and form a merkle tree. We
maintain an index of path to content-addressable items.
Resource reference paths are rooted at `/api/v1/ref/<path>`.
```json
{
"objectId": <merkle-hash>,
"content_address": <content-hash>,
"path": "/path/name0",
"dependents": [
{
"path": "path/name1",
"content_address": <content-hash>,
"objectId": <merkle-hash>, content: <payload>
},
{
"path": "path/name2",
"content_address": <content-hash>,
"objectId": <merkle-hash>, content: <payload>
}
],
}
```
Resource references contain a payload with the objectID and a list of any
dependent resources. They support the following operations
* `GET`
* `POST`
* `PUT`
* `DELETE`
* `HEAD`
`HEAD` requests return only the objectId in the payload. Primarily used to detect
if a reference needs to be updated on the client or not.
Resource Requests can be expanded to their object reference payloads at any
configurable depth with the query parameters `?depth=<number>` or to the full
tree depth with `?full=true`. This will add recursive dependent sections to the
content key.
```json
{
"objectId": <merkle-hash>,
"path": "/path/name0",
"dependents": [
{
"objectId": <merkle-hash>,
"path": "path/name1",
"content": {
"objectId": <merkle-hash>,
"dependents": [
{
"path": "path/name1",
"content_address": <content-hash>,
"objectId": <merkle-hash>, content: <payload>
},
{
"path": "path/name2",
"content_address": <content-hash>,
"objectId": <merkle-hash>, content: <payload>
}
],
}
}
]
}
```
### Reserved References
* `/api/v1/ref/all/<username>` The root of the resouce tree. List all sub
resources that the user has access too.
* `/api/v1/ref/user/<username>` The user information.
### Content-Addressable Query API
The content addressable store is considered immutable. You do not delete from
it. We may garbage collect at some point as a storage optimization.
Content addressable paths are rooted at `/api/v1/object/<content-hash>`.
Their payloads are whatever the contents serialize to in json and support the following
operations.
* `GET`
* `POST`
## Syncrhonization
### Bootstrapping
* Load `/api/v1/ref/all/<username>` and then follow the sub resources to
load the entire dataset locally making sure to keep the content-addresses
around for comparison.
# Benchmarking
## Bootstrapping benchmark tests
* Server side loading
* Client side loading
* WebSocket?