Add proper API docs

This commit is contained in:
Marcel Klehr 2019-09-15 00:48:23 +02:00
parent e64c4a18a9
commit 445d4670ef
10 changed files with 1002 additions and 471 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.*.sw*
js
build
_build
node_modules
vendor

471
API.md
View File

@ -1,471 +0,0 @@
# REST API
This is the REST API exposed by Nextcloud Bookmarks.
## Authentication
In order to access the REST API you will need to provide credentials for the user on behalf of which you'd
like to access the bookmarks app. This can be done using Basic Auth and must happen for every request.
### Query bookmarks
```
GET
/index.php/apps/bookmarks/public/rest/v2/bookmark
```
Parameters:
- (optional) `tags[]`: array of tags that bookmarks returned by the endpoint should have
- (optional) `conjunction`: Set to `and` to require all tags to be present, `or` if one should suffice. Default: `or`
- (optional) `page`: if this is non-negative, results will be paginated by 10 bookmarks a page. Default: `0`
- (optional) `sortby`: The column to sort the results by; one of `url`, `title`, `description`, `public`, `lastmodified`, `clickcount`. Default: `lastmodified`.
- (optional) `search[]`: An array of words to search for in the following columns `url`, `title`, `description`
- (optional) `user`: Instead of returning the bookmarks of the current user, return the public bookmarks of the user passed as this parameter.
- (optional) `folder`: Only return bookmarks that are direct children of the folder with the passed ID. The root folder has id `-1`.
- (optional) `url`: Only return bookmarks with this URL. This will only ever return just one bookmark or none, because the app doesn't store duplicates. Thus, with this parameter you can test whether a URL exists in the user's bookmarks. This parameter cannot be mixed with the others.
Example:
```
GET
/index.php/apps/bookmarks/public/rest/v2/bookmark?tags[]=firsttag&tags[]=secondtag&page=-1
```
```json
{
"status": "success",
"data": [{ "id": "7", "title": "Google", "tags": ["firsttag"] /*...*/ }]
}
```
### Create a bookmark
```
POST
/index.php/apps/bookmarks/public/rest/v2/bookmark
```
Parameters:
- `url`: the url of the new bookmark
- (optional) `item[tags][]`: Array of tags for this bookmark (these needn't exist and are created on-the-fly)
- (optional) `title`: the title of the bookmark. If absent the title of the html site referenced by `url` is used
- (optional) `is_public`: Set this parameter (without a value) to mark the new bookmark as public, so that other users can see it
- (optional) `description`: A description for this bookmark
- (optional) `folders`: An array of IDs of the folders this bookmark should reside in.
Example:
```
POST /index.php/apps/bookmarks/public/rest/v2/bookmark?url=http%3A%2F%2Fgoogle.com&title=Google&description=in%20case%20you%20forget&item[tags][]=search-engines&item[tags][]=uselessbookmark
```
```json
{
"status": "success",
"item": {
"id": "7",
"url": "http://google.com",
"title": "Google"
//...
}
}
```
### Get a bookmark
```
GET /index.php/apps/bookmarks/public/rest/v2/bookmark/:id
```
- `id`: The id of the bookmark to edit
Parameters:
- (optional) `user`: The user this bookmark belongs to
Example:
```
GET /index.php/apps/bookmarks/public/rest/v2/bookmark/7
```
```json
{
"status": "success",
"item": {
"id": "7",
"url": "http://google.com",
"title": "Boogle"
//...
}
}
```
### Edit a bookmark
```
PUT /index.php/apps/bookmarks/public/rest/v2/bookmark/:id
```
- `id`: The id of the bookmark to edit
Parameters:
- `record_id`: The id of the bookmark to edit
- (optional) `url`: The new url
- (optional) `item[tags][]`: the new tags. Existing tags will be deleted.
- (optional) `title`: The new title
- (optional) `is_public`: Set or leave unset to set the new public status.
- (optional) `description`: The new description.
- (optional) `folders`: The folders this bookmark should reside in.
Example:
```
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"
//...
}
}
```
### Delete a bookmark
```
DELETE /index.php/apps/bookmarks/public/rest/v2/bookmark/:id
```
- `id`: The bookmark to delete
Note: This will remove the bookmark from all folders it resided in.
Parameters: _None_
Example:
```
DELETE /index.php/apps/bookmarks/public/rest/v2/bookmark/7
```
```json
{ "status": "success" }
```
### List all tags
```
GET /index.php/apps/bookmarks/public/rest/v2/tag
```
Parameters: _None_
Example:
```
GET /index.php/apps/bookmarks/public/rest/v2/tag
```
```
["politics", "satire", "tech", "music", "art", "blogs", "personal"]
```
### Delete a tag
```
DELETE /index.php/apps/bookmarks/public/rest/v2/tag
```
Parameters:
- `old_name`: the name of the tag to delete
Example:
```
DELETE /index.php/apps/bookmarks/public/rest/v2/tag?old_name=mytag
```
```
{ "status": "success" }
```
### Rename a tag
```
POST /index.php/apps/bookmarks/public/rest/v2/tag
```
Parameters:
- `old_name`: The name of the tag to rename
- `new_name`: The new name of the tag
Example:
```
POST /index.php/apps/bookmarks/public/rest/v2/tag?old_name=politics&new_name=satire
```
```
{ "status": "success"}
```
### List folders
```
GET /index.php/apps/bookmarks/public/rest/v2/folder
```
Parameters:
- (optional) `root`: The id of the folder to start listing folders from. (Default: `-1`; the root folder)
- (optional) `layers`: How many layers of folders to return at max. By default, all layers are returned.
Example:
```
GET /index.php/apps/bookmarks/public/rest/v2/folder
```
```
{"status": "success", "data": [
{"id": "1", "title": "work", "parent_folder": "-1"},
{"id": "2", "title": "personal", "parent_folder": "-1", "children": [
{"id": "3", "title": "garden", "parent_folder": "2"},
{"id": "4", "title": "music", "parent_folder": "2"}
]},
]}
```
### Show single folder
```
GET /index.php/apps/bookmarks/public/rest/v2/folder/:id
```
- `id`: The id of the folder to show
Parameters: _None_
Example:
```
GET /index.php/apps/bookmarks/public/rest/v2/folder/2
```
```
{"status": "success", "item": {"id": "2", "title": "personal", "parent_folder": "-1"}}
```
### Create folder
```
POST /index.php/apps/bookmarks/public/rest/v2/folder
```
Parameters:
- `title`: The title of the new folder
- `parent_folder`: The id of the parent folder for the new folder
Example:
```
POST /index.php/apps/bookmarks/public/rest/v2/folder
{"title": "sports", "parent_folder": "-1"}
```
```
{ "status": "success", "item": {"id": 5, "title": "sports", "parent_folder": "-1"}}
```
### Edit folders
```
PUT /index.php/apps/bookmarks/public/rest/v2/folder/:id
```
Parameters:
- (optional) `title`: The new title for the folder
- (optional) `parent_folder`: The new parent to move the folder to
Example:
```
PUT /index.php/apps/bookmarks/public/rest/v2/folder/5
{"title": "physical activity"}
```
```
{ "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 `sha256(to_json({title: folderTitle, children: childrenHashes}))` with the title being unset in case of the root folder
- `hashBookmark(id, fields)`
- for all entries in `fields`
- set `object[field]` to the value of the associated field of the bookmark
- Return `sha256(to_json(object))`
- `to_json`: A JSON stringification algorithm that adds no unnecessary white-space and doesn't use JSON's backslash escaping unless necessary (character set is UTF-8)
- `sha256`: The SHA-256 hashing algorithm
### Delete folders
```
DELETE /index.php/apps/bookmarks/public/rest/v2/folder/:id
```
- `id`: The id of the folder to remove
Parameters: _None_
Example:
```
DELETE /index.php/apps/bookmarks/public/rest/v2/folder/2
```
```
{"status": "success"}
```
### Put bookmarks into a folder
```
POST /index.php/apps/bookmarks/public/rest/v2/folder/:id/bookmarks/:bookmark
```
- `id`: The id of the folder
- `bookmark`: The id of the bookmark to put into the folder
Parameters: _None_
Example:
```
POST /index.php/apps/bookmarks/public/rest/v2/folder/2/bookmarks/15
```
```
{"status": "success"}
```
### Remove a bookmark from a folder
```
DELETE /index.php/apps/bookmarks/public/rest/v2/folder/:id/bookmarks/:bookmark
```
- `id`: The id of the folder
- `bookmark`: The id of the bookmark to put into the folder
Parameters: _None_
Example:
```
DELETE /index.php/apps/bookmarks/public/rest/v2/folder/2/bookmarks/15
```
```
{"status": "success"}
```
### Order folder contents
```
PATCH /index.php/apps/bookmarks/public/rest/v2/folder/:id/childorder
```
- `id`: the folder's ID
Parameters:
- `data`: An array of children objects with two keys each: `type` and `id`, where type is either `bookmark` or `folder`
Example:
```
PATCH /index.php/apps/bookmarks/public/rest/v2/folder/2/childorder
{"data": [
{"type": "folder", "id": "17"},
{"type": "bookmark", "id": "204"},
{"type": "bookmark", "id": "192"},
{"type": "bookmark", "id": "210"}
]}
```
```
{ "status": "success"}
```
### Retrieve current order of folder contents
```
GET /index.php/apps/bookmarks/public/rest/v2/folder/:id/childorder
```
- `id`: the folder's ID
Parameters: _None_
Example:
```
GET /index.php/apps/bookmarks/public/rest/v2/folder/2/childorder
```
```
{ "status": "success", "data": [
{"type": "folder", "id": "17"},
{"type": "bookmark", "id": "204"},
{"type": "bookmark", "id": "192"},
{"type": "bookmark", "id": "210"}
]}
```

16
doc/.editorconfig Normal file
View File

@ -0,0 +1,16 @@
root = true
[*]
indent_style = tab
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.rst]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false

19
doc/Makefile Normal file
View File

@ -0,0 +1,19 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

5
doc/authentication.rst Normal file
View File

@ -0,0 +1,5 @@
Authentication
==============
In order to access the REST API you will need to provide credentials for the user on behalf of which you'd
like to access the bookmarks app. This should be done using Basic Auth and must happen for every request.

234
doc/bookmark.rst Normal file
View File

@ -0,0 +1,234 @@
=========
Bookmarks
=========
.. contents::
Bookmark model
==============
A bookmark has at least the following properties
.. object:: Bookmark
:param int id: The bookmarks unique id
:param string url: The Uniform Resource Locator that this bookmark represents
:param string title: A short humanly readable label for the bookmark
:param string description: A longer description or note on the bookmark
:param array tags: A list of tags this bookmark is tagged with
:param array folders: The folders this bookmark has been added to
Query bookmarks
===============
.. get:: /public/rest/v2/bookmark
:synopsis: Filter and query all bookmarks by the authenticated user.
.. versionadded:: 0.11.0
:query conjunction: Set to `and` to require all tags to be present, ``or`` if one should suffice. Default: ``or``
:query tags[]: An array of tags that bookmarks returned by the endpoint should have
:query page: if this is non-negative, results will be paginated by 10 bookmarks a page. Default: ``0``
:query sortby: The column to sort the results by; one of ``url``, ``title``, ``description``, ``public``, ``lastmodified``, ``clickcount``. Default: ``lastmodified``.
:query search[]: An array of words to search for in the following columns `url`, `title`, `description`
:query user: Instead of returning the bookmarks of the current user, return the public bookmarks of the user passed as this parameter.
:query folder: Only return bookmarks that are direct children of the folder with the passed ID. The root folder has id `-1`.
:query url: Only return bookmarks with this URL. This will only ever return just one bookmark or none, because the app doesn't store duplicates. Thus, with this parameter you can test whether a URL exists in the user's bookmarks. This parameter cannot be mixed with the others.
:>json string status: ``success`` or ``error``
:>json array data: The list of resulting bookmarks
**Example:**
.. sourcecode:: http
GET /index.php/apps/bookmarks/public/rest/v2/bookmark?tags[]=firsttag&tags[]=secondtag&page=-1 HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"data": [{ "id": "7", "title": "Google", "tags": ["firsttag"] }]
}
Create a bookmark
=================
.. post:: /public/rest/v2/bookmark
:synopsis: Create a bookmark
.. versionadded:: 0.11.0
:param id: the url of the new bookmark
:param array tags: Array of tags for this bookmark (these needn't exist and are created on-the-fly; this used to be `item[tags][]`, which is now deprecated)
:param string title: the title of the bookmark. If absent the title of the html site referenced by `url` is used
:param boolean is_public: Set this parameter (without a value) to mark the new bookmark as public, so that other users can see it
:param string description: A description for this bookmark
:param array folders: An array of IDs of the folders this bookmark should reside in.
:>json string status: ``success`` or ``error``
:>json object item: The created bookmark
**Example:**
.. sourcecode:: http
POST /index.php/apps/bookmarks/public/rest/v2/bookmark?tags[]=firsttag&tags[]=secondtag&page=-1 HTTP/1.1
Host: example.com
Accept: application/json
{
"url": "http://google.com",
"title": "Google",
"description":"in case i forget",
"tags": ["search-engines", "uselessbookmark"]
}
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"item": {
"id": "7",
"url": "http://google.com",
"title": "Google",
"description":"in case i forget",
"tags": ["search-engines", "uselessbookmark"],
"folders": ["-1"]
}
}
Get a bookmark
==============
.. get:: /public/rest/v2/bookmark/(int:id)
:synopsis: Retrieve a bookmark
.. versionadded:: 0.11.0
:>json string status: ``success`` or ``error``
:>json object item: The retrieved bookmark
**Example:**
.. sourcecode:: http
GET /index.php/apps/bookmarks/public/rest/v2/bookmark/7 HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"item": {
"id": "7",
"url": "http://google.com",
"title": "Google",
"description":"in case i forget",
"tags": ["search-engines", "uselessbookmark"],
"folders": ["-1"]
}
}
Edit a bookmark
===============
.. put:: /public/rest/v2/bookmark/(int:id)
:synopsis: Edit a bookmark
.. versionadded:: 0.11.0
:param id: the url of the new bookmark
:param array tags: Array of tags for this bookmark (these needn't exist and are created on-the-fly; this used to be `item[tags][]`, which is now deprecated)
:param string title: the title of the bookmark. If absent the title of the html site referenced by `url` is used
:param boolean is_public: Set this parameter (without a value) to mark the new bookmark as public, so that other users can see it
:param string description: A description for this bookmark
:param array folders: An array of IDs of the folders this bookmark should reside in.
:>json string status: ``success`` or ``error``
:>json object item: The new bookmark after editing
**Example:**
.. sourcecode:: http
PUT /index.php/apps/bookmarks/public/rest/v2/bookmark/7 HTTP/1.1
Host: example.com
Accept: application/json
{ "title": "Boogle" }
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"item": {
"id": "7",
"url": "http://google.com",
"title": "Boogle",
"description":"in case i forget",
"tags": ["search-engines", "uselessbookmark"],
"folders": ["-1"]
}
}
Delete a bookmark
=================
.. delete:: /public/rest/v2/bookmark/(int:id)
:synopsis: Delete a bookmark
.. versionadded:: 0.11.0
:>json string status: ``success`` or ``error``
**Example:**
.. sourcecode:: http
DELETE /index.php/apps/bookmarks/public/rest/v2/bookmark/7 HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success"
}

176
doc/conf.py Normal file
View File

@ -0,0 +1,176 @@
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = u'Nextcloud Bookmarks'
copyright = u'2019, Marvin Thomas Rabe, Stefan Klemm, Arthur Schiwon, Marcel Klehr'
author = u'Marvin Thomas Rabe, Stefan Klemm, Arthur Schiwon, Marcel Klehr'
# The short X.Y version
version = u''
# The full version, including alpha/beta/rc tags
release = u''
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinxcontrib.httpdomain'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None
primary_domain = 'http'
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'NextcloudBookmarksdoc'
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'NextcloudBookmarks.tex', u'Nextcloud Bookmarks Documentation',
u'Marvin Thomas Rabe, Stefan Klemm, Arthur Schiwon, Marcel Klehr', 'manual'),
]
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'nextcloudbookmarks', u'Nextcloud Bookmarks Documentation',
[author], 1)
]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'NextcloudBookmarks', u'Nextcloud Bookmarks Documentation',
author, 'NextcloudBookmarks', 'One line description of project.',
'Miscellaneous'),
]
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''
# A unique identification for the text.
#
# epub_uid = ''
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']

426
doc/folder.rst Normal file
View File

@ -0,0 +1,426 @@
=======
Folders
=======
.. contents::
Folder model
============
.. object:: Folder
:param int id: The folder's unique id
:param string title: The humanly-readable label for the folder
:param int parent_folder: The folder's parent folder
.. note::
The root folder has the magic id ``-1``, which is the same for every user.
Get full hierarchy
=============
.. get:: /public/rest/v2/folder
:synopsis: Retrieve the folder hierarchy
.. versionadded:: 0.15.0
:query int root: The id of the folder whose contents to retrieve (Default: ``-1``, which is the root folder)
:query int layers: How many layers of folders to return at max. By default, all layers are returned.
:>json string status: ``success`` or ``error``
:>json array data: The folder hierarchy
:>jsonarr int id: The id of the folder
:>jsonarr string title: the folder title
:>jsonarr int parent_folder: the folder's parent folder
:>jsonarr array children: The folder's children (folders only)
**Example:**
.. sourcecode:: http
GET /index.php/apps/bookmarks/public/rest/v2/folder HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success", "data": [
{"id": "1", "title": "work", "parent_folder": "-1"},
{"id": "2", "title": "personal", "parent_folder": "-1", "children": [
{"id": "3", "title": "garden", "parent_folder": "2"},
{"id": "4", "title": "music", "parent_folder": "2"}
]},
]
}
Get single folder
=================
.. get:: /public/rest/v2/folder/(int:id)
:synopsis: Retrieve a single folder
.. versionadded:: 0.15.0
:>json string status: ``success`` or ``error``
:>json object item: The retrieved folder
**Example:**
.. sourcecode:: http
GET /index.php/apps/bookmarks/public/rest/v2/folder/2 HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"item": {
"id": "2",
"title": "My Personal Bookmarks",
"parent_folder": "-1"
}
}
Create a folder
===============
.. post:: /public/rest/v2/folder
:synopsis: Create a new folder
.. versionadded:: 0.15.0
:<json string title: The title of the new folder
:<json int parent_folder: The id of the parent folder for the new folder
:>json string status: ``success`` or ``error``
:>json object item: The new folder
**Example:**
.. sourcecode:: http
POST /index.php/apps/bookmarks/public/rest/v2/folder HTTP/1.1
Host: example.com
Accept: application/json
{"title": "sports", "parent_folder": "-1"}
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"item": {
"id": 5,
"title": "sports",
"parent_folder": "-1"
}
}
Edit a folder
=============
.. put:: /public/rest/v2/folder/(int:id)
:synopsis: Edit an existing folder
.. versionadded:: 0.15.0
:<json string title: The title of the new folder
:<json int parent_folder: The id of the parent folder of the folder
:>json string status: ``success`` or ``error``
:>json object item: The new folder
**Example:**
.. sourcecode:: http
POST /index.php/apps/bookmarks/public/rest/v2/folder/5 HTTP/1.1
Host: example.com
Accept: application/json
{"title": "optional physical activity"}
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"item": {
"id": 5,
"title": "optional physical activity",
"parent_folder": "-1"
}
}
Hash a folder
=============
.. get:: /public/rest/v2/folder/(int:id)/hash
:synopsis: Compute the hash of a folder
.. versionadded:: 1.0.0
:param array fields: All bookmarks fields that should be hashed (default: ``title``, ``url``)
:>json string status: ``success`` or ``error``
:>json string data: The SHA256 hash in hexadecimal notation
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: return ``hashFolder(id, fields)``
- ``hashFolder(id, fields)``
- set ``childrenHashes`` to empty array
- 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)``
- set ``object`` to an empty dictionary
- set ``object[title]`` to the title of the folder, if this is not the root folder
- set ``object[children]`` to the value of ``childrenHashes``
- set ``json`` to ``to_json(object)``
- Return ``sha256(json)``
- ``hashBookmark(id, fields)``
- set ``object`` to an empty dictionary/hashmap
- for all entries in ``fields``
- set ``object[field]`` to the value of the associated field of the bookmark
- Return ``sha256(to_json(object))``
- ``to_json``: A JSON stringification algorithm that adds no unnecessary white-space and doesn't use JSON's backslash escaping unless necessary (character set is UTF-8)
- ``sha256``: The SHA-256 hashing algorithm
**Example:**
.. sourcecode:: http
GET /index.php/apps/bookmarks/public/rest/v2/folder/5/hash HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{ "status": "success", "data": "6543a23c78aefd0274f3ac98de98723" }
Delete a folder
===============
.. delete:: /public/rest/v2/folder/(int:id)
:synopsis: Delete a folder
.. versionadded:: 0.15.0
:>json string status: ``success`` or ``error``
:>json object item: The new folder
**Example:**
.. sourcecode:: http
DELETE /index.php/apps/bookmarks/public/rest/v2/folder/5 HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success"
}
Add bookmark to folder
======================
.. post:: /public/rest/v2/folder/(int:folder_id)/bookmarks/(int:bookmark_id)
:synopsis: Add a bookmark to a folder
.. versionadded:: 0.15.0
:>json string status: ``success`` or ``error``
**Example:**
.. sourcecode:: http
POST /index.php/apps/bookmarks/public/rest/v2/folder/5/bookmarks/418 HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success"
}
Remove bookmark from folder
===========================
.. delete:: /public/rest/v2/folder/(int:folder_id)/bookmarks/(int:bookmark_id)
:synopsis: Remove a bookmark from a folder
.. versionadded:: 0.15.0
:>json string status: ``success`` or ``error``
**Example:**
.. sourcecode:: http
DELETE /index.php/apps/bookmarks/public/rest/v2/folder/5/bookmarks/418 HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success"
}
Get folder's content order
==========================
.. get:: /public/rest/v2/folder/(int:folder_id)/childorder
:synopsis: Retrieve the order of contents of a folder
.. versionadded:: 0.15.0
:>json string status: ``success`` or ``error``
:>json array data: An ordered list of child items
:>jsonarr string type: Either ``folder`` or ``bookmark``
:>jsonarr string id: The id of the bookmark or folder
**Example:**
.. sourcecode:: http
GET /index.php/apps/bookmarks/public/rest/v2/folder/5/childorder HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"data": [
{"type": "folder", "id": "17"},
{"type": "bookmark", "id": "204"},
{"type": "bookmark", "id": "192"},
{"type": "bookmark", "id": "210"}
]
}
Set folder's content order
==========================
.. patch:: /public/rest/v2/folder/(int:folder_id)/childorder
:synopsis: Set the order of contents of a folder
.. versionadded:: 0.15.0
:<json array data: An ordered list of child items
:<jsonarr string type: Either ``folder`` or ``bookmark``
:<jsonarr string id: The id of the bookmark or folder
:>json string status: ``success`` or ``error``
**Example:**
.. sourcecode:: http
PATCH /index.php/apps/bookmarks/public/rest/v2/folder/5/childorder HTTP/1.1
Host: example.com
Accept: application/json
{
"status": "success",
"data": [
{"type": "folder", "id": "17"},
{"type": "bookmark", "id": "204"},
{"type": "bookmark", "id": "192"},
{"type": "bookmark", "id": "210"}
]
}
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success"
}

22
doc/index.rst Normal file
View File

@ -0,0 +1,22 @@
Welcome to the docs for the Nextcloud Bookmarks API!
====================================================
The Nextcloud Bookmarks app provides you with a web interface for collecting and organizing bookmarks to the sites on the web that are precious to you. You can browse and filter your bookmarks via tags and folders and by using the built-in search feature. Furthermore, in order to access your bookmarks anywhere, it also allows you to synchronize third-party clients via a built-in REST API.
These docs describe how to use this API.
.. toctree::
:caption: Contents:
authentication
bookmark
tag
folder
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

98
doc/tag.rst Normal file
View File

@ -0,0 +1,98 @@
====
Tags
====
.. contents::
Tag model
=========
.. object:: Tag
A tag is just a string that can be added as a label to a bookmark
Get list of tags
================
.. get:: /public/rest/v2/tag
:synopsis: Retrieve a list of tags
.. versionadded:: 0.11.0
**Example:**
.. sourcecode:: http
GET /index.php/apps/bookmarks/public/rest/v2/tag HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
["politics", "satire", "tech", "music", "art", "blogs", "personal"]
Delete a tag
============
.. delete:: /public/rest/v2/tag/(string:tag)
:synopsis: Delete a tag
.. versionadded:: 0.11.0
:>json string status: ``success`` or ``error``
**Example:**
.. sourcecode:: http
DELETE /index.php/apps/bookmarks/public/rest/v2/tag/politics HTTP/1.1
Host: example.com
Accept: application/json
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{ "status": "success" }
Rename a tag
============
.. put:: /public/rest/v2/tag/(string:tag)
:synopsis: Rename a tag
.. versionadded:: 0.11.0
:<json string name: The new name for the tag
:>json string status: ``success`` or ``error``
**Example:**
.. sourcecode:: http
PUT /index.php/apps/bookmarks/public/rest/v2/tag/politics HTTP/1.1
Host: example.com
Accept: application/json
{ "name": "satire" }
**Response:**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{ "status": "success" }