Using the Kademi JSON Database

2019-10-08 19:54:00.0
Developers

If you need to store arbitrary data structures you can use Kademi's built in JSON database, imaginatively called KongoDB.

This allows you to create and edit documents which can be retrieved by REST API calls with ajax, or can be used server side with templating.

Getting started with JSON Documents

To get started, first make sure Kongo is enabled in your account, and for the website you want to use it in:

Then go into the KongDB management screen and create your first database. Here i've created one called milton-releases:

Now you might want to manually create a record. Click on Manage to manage the database then open the Records tab, then click Add Record to open the new record dialog. All three fields are mandatory.

Note that the JSON data must be properly formatted. That means quotes around property names!

The end result should look something like this:

Using JSON Documents in Templating

To use a JSON document in server side template code, you first need to locate the document by its path. The path is the same as the actual href to locate the document from the browser, and is in this form:

/jsondb/[database name]/[document name]

For example, in my case the current version is in a document:

/jsondb/milton-releases/current

To do the lookup in server side templating use the find method on any resource, and then use the jsonObject, and then you can reference any properties in the document. Eg:

$page.find("/jsondb/milton-releases/current").jsonObject.version

 

You can also use server side templating methods to get a list of documents by type by calling method on the json database folder:

#foreach( $release in $page.find("/jsondb/milton-releases/").findByType("release")

 

  • $release.jsonObject.version

 

#end

 

And you can use the search method to execute elasticsearch queries over your documents:

		var search = {
		"query": { "match": { "account_number": 20 } }
		};
		var jsonSearch = JSON.stringify(search);
		var results = projects.search(jsonSearch); // results is SearchResponse
		

See here for more information on elastic queries

Accessing JSON Documents with the REST API

To be able to access JSON documents from the REST api the database must be configured to allow it by selecting the website (or allow access from any website flag) and the Allow REST flag.

Then you can simply load documents from their href:

		            $(function(){
		                $.ajax({
		                    type: 'GET',
		                    url: "/jsondb/milton-releases/current",
		                    dataType: "json",
		                    success: function(response) {
		                        alert("Version is " + response.currentVersion);
		                    },
		                    error: function(resp) {             
		                        flog("failed", resp);
		                    }
		                });
		            });

Creating a JSON Database in Application initialisation

You might have a custom application which requires a json database. Rather then rely on your users to create it manually, you can use an application enabled callback. First add the onAppEnabled method to your controllers.xml file

  
    /APP-INF/app.js  

 

Then create that method in your app app.js file:

function initApp(orgRoot, webRoot, enabled){
    log.info("initApp: orgRoot={}", orgRoot);
    if( webRoot ){
        log.info("I'm in a website {}", webRoot.websiteName );
        var dbs = orgRoot.find('jsondb');
        var dbName = "coffeeOrders-" + webRoot.websiteName;
        var db = dbs.child(dbName);
        
        if( db === null ) {
            log.info("No database {} for website {}, so create it", dbName,webRoot.websiteName);
            db = dbs.createDb(dbName, "Coffee Orders - " + webRoot.websiteName, "helloWorld/coffeeOrderTemplate");
            db.website = webRoot.websiteName;
        }
    } else {
        log.info("I'm in an organisation");
    }
}

Writing AJAX controller methods

You will often want to write controller methods, either for websites (in WEB-INF) or custom applications (in APP-INF) which provide access to your JSON databases through ajax requests.

Often these requests will be anonymous, ie there is no logged in user. All operations on JSON databases must be in the context of a user, so for anonymous requests you use the runAsUser method on the security manager

controllerMappings
        .websiteController()
        .path("/orderCoffee/")
        .enabled(true)
        .addMethod("POST", "handleCoffee", "coffeeType")
        .build();


function handleCoffee(page, params) {
    log.info("handleCoffee");
    var runAsUser = "jo"; // todo: should be a setting

    var dbName = "coffeeOrders-" + page.find("/").websiteName;
    var db = page.find('/jsondb/' + dbName);
    if( db === null ) {
        log.info("Database not found {}", dbName);
        return;
    }
    var recordId = formatter.randomGuid;
    securityManager.runAsUser(runAsUser, function(){
        var newOrder = {
            coffeeType : params.coffeeType,
            size : params.size,
            sugar : params.sugar
        };
        var json = JSON.stringify(newOrder);
        var newRecord = db.createNew(recordId, json, 'coffeeOrder');
        log.info("Created new order");
    });
    
    log.info("return json status");
    return views.jsonResult(true);
}

 

In this case we are returning a JsonResult object which is serialised as json. The views object containers several other methods for returning data and content in different ways.