Add REST enpoints for hashing

Signed-off-by: Marcel Klehr <mklehr@gmx.net>
This commit is contained in:
Marcel Klehr 2019-04-22 16:22:23 +02:00
parent 22792a5655
commit 0e3103afae
4 changed files with 95 additions and 24 deletions

88
API.md
View File

@ -33,8 +33,8 @@ GET
```json
{
"status": "success",
"data": [{ "id": "7", "title": "Google", "tags": ["firsttag"] /*...*/ }]
"status": "success",
"data": [{ "id": "7", "title": "Google", "tags": ["firsttag"] /*...*/ }]
}
```
@ -62,13 +62,13 @@ POST /index.php/apps/bookmarks/public/rest/v2/bookmark?url=http%3A%2F%2Fgoogle.c
```json
{
"status": "success",
"item": {
"id": "7",
"url": "http://google.com",
"title": "Google"
//...
}
"status": "success",
"item": {
"id": "7",
"url": "http://google.com",
"title": "Google"
//...
}
}
```
@ -92,13 +92,13 @@ GET /index.php/apps/bookmarks/public/rest/v2/bookmark/7
```json
{
"status": "success",
"item": {
"id": "7",
"url": "http://google.com",
"title": "Boogle"
//...
}
"status": "success",
"item": {
"id": "7",
"url": "http://google.com",
"title": "Boogle"
//...
}
}
```
@ -128,13 +128,13 @@ PUT /index.php/apps/bookmarks/public/rest/v2/bookmark/7?record_id=7&title=Boogle
```json
{
"status": "success",
"item": {
"id": "7",
"url": "http://google.com",
"title": "Boogle"
//...
}
"status": "success",
"item": {
"id": "7",
"url": "http://google.com",
"title": "Boogle"
//...
}
}
```
@ -292,7 +292,7 @@ POST /index.php/apps/bookmarks/public/rest/v2/folder
### Edit folders
```
PUT /index.php/apps/bookmarks/public/rest/v2/folder
PUT /index.php/apps/bookmarks/public/rest/v2/folder/:id
```
Parameters:
@ -312,6 +312,46 @@ PUT /index.php/apps/bookmarks/public/rest/v2/folder/5
{ "status": "success", "item": {"id": 5, "title": "physical activity", "parent_folder": "-1"}}
```
### Hash folders
```
GET /index.php/apps/bookmarks/public/rest/v2/folder/:id/hash
```
Parameters:
- (optional) `fields[]`: All bookmarks fields that should be hashed (default: `title`, `url`)
Example:
```
GET /index.php/apps/bookmarks/public/rest/v2/folder/5/hash
```
```
{ "status": "success", "data": "65432378"}
```
Description:
This endpoint is useful for synchronizing data between the server and a client. By comparing the hash of the data on your client with the hash from the server you can figure out which parts of the tree have changed.
The algorithm works as follows:
- Hash endpoint: `hashFolder(id, fields)`
- `hashFolder(id, fields)`
- for all children of the folder
- if it's a folder
- add to `childrenHashes`: `hashFolder(folderId, fields)`
- if it's a bookmark
- add to `childrenHashes`: `hashBookmark(bookmarkId, fields)`
- Return `murmur2(to_json({title: folderTitle, children: childrenHashes}))`
- `hashBookmark(id, fields)`
- for all entries in `fields`
- set `object[field]` to the value of the associated field of the bookmark
- Return `murmur2(to_json(object))`
- `murmur2`: [The murmur2 hashing algorithm](https://en.wikipedia.org/wiki/MurmurHash)
### Delete folders
```

View File

@ -47,6 +47,7 @@ $application->registerRoutes($this, ['routes' => [
['name' => 'internal_folders#add_folder', 'url' => '/folder', 'verb' => 'POST'],
['name' => 'internal_folders#edit_folder', 'url' => '/folder/{folderId}', 'verb' => 'PUT'],
['name' => 'internal_folders#delete_folder', 'url' => '/folder/{folderId}', 'verb' => 'DELETE'],
['name' => 'internal_folders#hash_folder', 'url' => '/folder/{folderId}/hash', 'verb' => 'GET'],
['name' => 'internal_folders#get_folder_children_order', 'url' => '/folder/{folderId}/childorder', 'verb' => 'GET'],
['name' => 'internal_folders#set_folder_children_order', 'url' => '/folder/{folderId}/childorder', 'verb' => 'PATCH'],
['name' => 'internal_folders#add_to_folder', 'url' => '/folder/{folderId}/bookmarks/{bookmarkId}', 'verb' => 'POST'],
@ -70,6 +71,7 @@ $application->registerRoutes($this, ['routes' => [
['name' => 'folders#add_folder', 'url' => '/public/rest/v2/folder', 'verb' => 'POST'],
['name' => 'folders#edit_folder', 'url' => '/public/rest/v2/folder/{folderId}', 'verb' => 'PUT'],
['name' => 'folders#delete_folder', 'url' => '/public/rest/v2/folder/{folderId}', 'verb' => 'DELETE'],
['name' => 'folders#hash_folder', 'url' => '/public/rest/v2/folder/{folderId}/hash', 'verb' => 'GET'],
['name' => 'folders#get_folder_children_order', 'url' => '/public/rest/v2/folder/{folderId}/childorder', 'verb' => 'GET'],
['name' => 'folders#set_folder_children_order', 'url' => '/public/rest/v2/folder/{folderId}/childorder', 'verb' => 'PATCH'],
['name' => 'folders#add_to_folder', 'url' => '/public/rest/v2/folder/{folderId}/bookmarks/{bookmarkId}', 'verb' => 'POST'],

View File

@ -118,6 +118,24 @@ class FoldersController extends ApiController {
}
}
/**
* @param int $folderId
* @param string[] $fields
* @return JSONResponse
*
* @NoAdminRequired
* @NoCSRFRequired
* @CORS
*/
public function hashFolder($folderId, $fields=['title', 'url']) {
try {
$hash = $this->bookmarks->hashFolder($this->userId, $folderId, $fields);
return new JSONResponse(['status' => 'success', 'data' => $hash]);
} catch (Exception $e) {
return new JSONResponse(['status' => 'error', 'data' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
}
}
/**
* @param int $folderId

View File

@ -102,6 +102,17 @@ class InternalFoldersController extends ApiController {
return $this->controller->editFolder($folderId, $title, $parent_folder);
}
/**
* @param int $folderId
* @param string[] $fields
* @return JSONResponse
*
* @NoAdminRequired
*/
public function hashFolder($folderId, $fields=['title', 'url']) {
return $this->controller->hashFolder($folderId, $fields);
}
/**
* @param int $root the id of the root folder whose descendants to return
* @param int $layers the number of layers of hierarchy too return