all repos — litestore @ 9e8f78c3f164e0e4c38bf6e2e53a9926db005f0e

A minimalist nosql document store.

Doc updates.
h3rald h3rald@h3rald.com
Sat, 15 Feb 2020 12:13:00 +0100
commit

9e8f78c3f164e0e4c38bf6e2e53a9926db005f0e

parent

3a9d41ade414b4b634ba524b9e51cc3bd3d13c9a

M build_guidebuild_guide

@@ -7,6 +7,8 @@ md/architecture.md

md/getting-started.md md/usage.md md/auth.md + md/custom_resources.md + md/litestore_js_object.md md/admin_app.md md/api.md md/api_info.md

@@ -14,6 +16,7 @@ md/api_dir.md

md/api_docs.md md/api_tags.md md/api_indexes.md + md/api_custom.md md/nim-api.md md/nim-api_high.md md/nim-api_low.md
M src/admin/js/components/navbar.jssrc/admin/js/components/navbar.js

@@ -19,13 +19,18 @@ {path: "/guide/getting-started", title: "Getting Started"},

{path: "/guide/usage", title: "Usage"}, {path: "/guide/auth", title: "Authorization"}, {path: "/guide/custom_resources", title: "Custom Resources"}, + {path: "/guide/litestore_js_object", title: caret+"LiteStore Global Object"}, {path: "/guide/admin_app", title: "Administration App"}, {path: "/guide/api", title: "HTTP API Reference"}, {path: "/guide/api_info", title: caret+"info (LiteStore Information)"}, {path: "/guide/api_dir", title: caret+"dir (LiteStore Directory)"}, {path: "/guide/api_docs", title: caret+"docs (LiteStore Documents)"}, {path: "/guide/api_tags", title: caret+"tags (LiteStore Tags)"}, + {path: "/guide/api_indexes", title: caret+"indexes (LiteStore Indexes)"}, {path: "/guide/api_custom", title: caret+"custom (LiteStore Custom Resources)"}, + {path: "/guide/nim-api", title: "Nim API Reference"}, + {path: "/guide/nim-api_high", title: caret+"High-Level Nim API"}, + {path: "/guide/nim-api_low", title: caret+"Low-Level Nim API"}, {path: "/guide/credits", title: "Credits"} ]; vm.taglinks = function(info){
M src/admin/md/api_custom.mdsrc/admin/md/api_custom.md

@@ -1,3 +1,12 @@

### custom (LiteStore Custom Resources) -TBD+> %note% +> API v6 Required +> +> This resource has been introduced in version 6 of the LiteStore API. + +The **custom** endpoint is used to exposed resources defined by the user by the means of JavaScript handlers. + +For example, if a handler is defined in a file called **test.js**, it will be accessible at the following URL: + +http://localhost:9500/custom/test/
M src/admin/md/custom_resources.mdsrc/admin/md/custom_resources.md

@@ -1,7 +1,49 @@

## Custom Resources -TBD +As of version 1.8.0, you can define your own custom resources using handlers coded in JavaScript. -### LiteStore Global Object +LiteStore embeds the [duktape](https://duktape.org/) lightweight JavaScript engine and therefore you can use all functionalities exposed by duktape in your code, plus access some LiteStore-specific properties and method through the special **LiteStore** global object. -TBD+Although writing extremely complex logic in a JavaScript handler may not be appropriate, it can be useful for certain use cases, such as: +* validating data before it is saved +* manipulate data before it is saved +* aggregating different types of data not accessible via a single query +* perform additional operation when accessing data, such as logging who requested it + +### Creating a JavaScript Handler + +Let's say you want to keep records of Italian vehicles identified by their number plate, which is in the following format: + +\[two-uppercase-letters\][three-digits\][two-uppercase-letters\] + +For example: AB467DX (OK, in reality there's a space between each set of digits/letters, but spaces in identifiers are ugly, so let's remove them!) + +Let's also say that Italian vehicle data will be managed by a custom resource called **vehicles**, therefore vehicles will be accessible at URLs similar to the following: + +* http://localhost:9500/docs/vehicles/AB467DX +* http://localhost:9500/docs/vehicles/CD569BW +* http://localhost:9500/docs/vehicles/EF981DE + +To make sure that valid IDs are used, we can create a file called **vehicles.js** and write the following handler code that intercepts all requests to that specific folder and: + +* denies POST requests +* returns an error in case of an invalid ID specified on a PUT request +* allows the request through otherwise + +``` +if (LiteStore.request.method === 'POST') { + LiteStore.response.code = 405; + LiteStore.response.content = JSON.stringify({error: 'No number plate specified.'}); + return; +} +if (LiteStore.request.method === 'PUT' && !LiteStore.request.path.match(/[A-Z]{2}[0-9]{3}[A-Z]{2}$/) { + LiteStore.response.code = 400; + LiteStore.response.content = JSON.stringify({error: 'Invalid number plate.'}); + return; +} + +LiteStore.passthrough(); +``` + + +### Mounting a Handler as a Custom Resource
A src/admin/md/litestore_js_object.md

@@ -0,0 +1,108 @@

+## LiteStore Global Object + +When creating JavaScript handlers for custom resources, you can use a special **LiteStore** global object to access the HTTP request to the resource, modify the HTTP response, and also access other LiteStore resources. + +### LiteStore.request + +The current HTTP request sent to access the current resource. + +#### Properties + +<dl> +<dt>method: string</dt> +<dd>The HTTP method used by the request, all uppercase (GET, POST, DELETE, PUT, PATCH, OPTIOONS, or HEAD).</dd> +<dt>url: object</dt> +<dd>An object containing the requested URL, split into the following String properties: <b>hostname</b>, <b>port</b>, <b>search</b>, <b>path</b>.</dd> +<dt>headers: object</dt> +<dd>An object containing the request headers, as keys and values.</dd> +</dl> + +### LiteStore.response + +The HTTP response to return to the client. + +<dl> +<dt>code: number</dt> +<dd>The HTTP return code, by default set to `200`.</dd> +<dt>content: string</dt> +<dd>The response content, by default set to `""`.</dd> +<dt>headers: object</dt> +<dd>The response headers, by default set to: +<pre><code> +{ + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": "Authorization, Content-Type", + "Server": "LiteStore/&lt;version&gt;", + "Content-Type": "application/json", + "Content-Length": "&lt;Automatically set to the length of the <b>content</b> property.&gt;" +} +</code></pre></dd> +</dl> + +### LiteStore.api + +Simple synchronous API to access LiteStore resources in a RESTful way, mimicking HTTP methods. + +All methods return a response object containing two String properties, **code** and **content**. + +<dl> +<dt>function get(resource: string, id: string, parameters: string): object</dt> +<dd>Retrieves the specified resource(s.). +<p> +Examples: +<ul> +<li><code>LiteStore.api.get('docs', 'test-folder/test.json')</code></li> +<li><code>LiteStore.api.get('docs', '', 'search=test&limit=20&offset=0')</code></li> +</ul> +</p> +</dd> +<dt>function post(resource: string, folder: string, body: string, contentType: string): object</dt> +<dd>Creates a new resource. +<p> +Examples: +<ul> +<li><code>LiteStore.api.post('docs', 'test-folder', 'test!', 'text/plain')</code></li> +<li><code>LiteStore.api.post('docs', '', '{"a": 1}', ?application/json')</code></li> +</ul> +</p> +</dd> +<dt>function put(resource: string, id: string, body: string, contentType: string): object</dt> +<dd>Creates or updates a specific resource. +<p> +Examples: +<ul> +<li><code>LiteStore.api.put('docs', 'test-folder/test1.txt', 'Another Test.', 'text/plain')</code></li> +<li><code>LiteStore.api.put('docs', 'test.json', '{"a": 2}', 'application/json')</code></li> +</ul> +</p> +</dd> +<dt>function patch(resource: string, id: string, body: string): object</dt> +<dd>Patches one or more fields of an existing resource. +<p> +Examples: +<ul> +<li><code>LiteStore.api.patch('docs', 'test-folder/test1.txt', '{"op":"add", "path":"/tags/3", "value":"test1"}')</code></li> +</ul> +</p> +</dd> +<dt>function delete(resource: string, id: string): object</dt> +<dd>Deletes a specific resource. +<p> +Examples: +<ul> +<li><code>LiteStore.api.delete('docs', 'test-folder/test1.txt')</code></li> +<li><code>LiteStore.api.delete('docs', 'test.json')</code></li> +</ul> +</p> +</dd> +<dt>function head(resource: string, id: string): object</dt> +<dd>Retrieves the metadata of one or more resources, without retrieving their contents. +<p> +Examples: +<ul> +<li><code>LiteStore.api.head('docs', 'test-folder/test1.txt')</code></li> +<li><code>LiteStore.api.head('docs')</code></li> +</ul> +</p> +</dd> +</dl>