Data Service Handler

Top  Previous  Next

Custom business logic code can extend or override the functionality of the Backendless data service by using the Backendless.ServerCode.Persistence  class. The class declares the before and after methods for all APIs available in the service. To create a handler for an event, server code must add a function to a method corresponding to the event. Persistence event handlers must establish the context of the events they subscribe to. A context is a specific table (or all tables) targeted by the API calls. The context is established by the first argument in the beforeXXX/afterXXX methods:

Backendless.ServerCode.Persistence.beforeCreate('table name', function(req) {
  //add your code here
});

It is also possible to create a "catch all" event handler, which would apply to all tables by using asterisk ( "*" ) in the place of the table name:

Backendless.ServerCode.Persistence.beforeCreate('*', function(req) {
  //add your code here
});

 

Data Object Class

Some data service events (create, update, etc) receive an instance of the object which is being saved/updated/etc in the Backendless storage. By default the object's data type is a plain (untyped) JavaScript object. It is possible to define a specific class which will be used to represent such data objects. This is the approach used by Backendless code generator for business logic. Consider the following example:

/* global Backendless */

'use strict';

class Order extends Backendless.ServerCode.PersistenceItem {
  constructor() {
    super();
    
    /**
     @name Order#customername
     @type String
     */
    this.customername = undefined;

  }
}

module.exports = Backendless.ServerCode.addType(Order);

Data object classes must observe the following rules of the framework:

Class must extend Backendless.ServerCode.PersistenceItem. This automatically adds objectId, created and updated properties to the class.
Class must define a constructor which calls super() and initializes class properties.
Class name must match the name of the corresponding data table.
Class properties must match the columns defined in the corresponding data table.
Class must be exported in the project using the following API:

module.exports = Backendless.ServerCode.addType(DATA-OBJECT-CLASS);

 

Available methods which trigger server-side events are:

Create

FindById

LoadRelations

Remove

Update

Describe

Find

FindFirst

FindLast

Create

These events occur when a client application sends an API request to store an object in the data storage. This is the initial persistence call (object does not have the objectId property assigned by Backendless).

Before create:

Backendless.ServerCode.Persistence.beforeCreate('table-name or *', function(req) {
  //add your code here
});

After create:

Backendless.ServerCode.Persistence.afterCreate('table-name or *', function(req) {
  //add your code here
});

where:

req.context- code runner context provides information about the application. For details see the CodeRunner™ Context topic.
req.item- Object to save in Backendless. The object is an untyped JS object unless there is a defined class corresponding to the table.
req.result-  contains the result of the default implementation of the method. If object creation is successful, the result is the persisted object, otherwise if the invocation resulted in an error, it is available through the res.error property.

 

Example:
 Generic handler - applies to all tables, except for the ones which have a dedicated event handler:

/* global Backendless */

/**
* @param {Object} req The request object contains information about the request
* @param {Object} req.context The execution context contains an information about
*                             application, current user and event
* @param {Object} req.item An item to create
*
* @returns {Object|Promise.<Object>|void} By returning a value you can stop 
*          further event propagation and return
*          a specific result to the caller
*/
Backendless.ServerCode.Persistence.beforeCreate('*', function(req) {
  //add your code here
});

Table specific handler, applies only to and will be used only with the API calls targeting the the table identified in the @Asset annotation:
/* global Backendless */

/**
* @param {Object} req The request object contains information about the request
* @param {Object} req.context The execution context contains an information about
*                 application, current user and event
* @param {Order} req.item An item to create
*
* @returns {Order|Promise.<Order>|void} By returning a value you can stop 
*          further event propagation and return
*          a specific result to the caller
*/
Backendless.ServerCode.Persistence.beforeCreate('Order', function(req) {
  //add your code here
});

The req.item object represents objects from the corresponding table. The structure of the class must match the table schema. For example, see the schema for the Order table and the corresponding Java class in the image and code snippet below:

order-object.zoom30

Class for the objects from the Order table:order.js:

/* global Backendless */

'use strict';

class Order extends Backendless.ServerCode.PersistenceItem {
  constructor() {
    super();
    
    /**
     @name Order#items
     @type Array.<OrderItem>
     */
    this.items = undefined;

  }
}

module.exports = Backendless.ServerCode.addType(Order);
orderitem.js:
/* global Backendless */

'use strict';

class OrderItem extends Backendless.ServerCode.PersistenceItem {
  constructor() {
    super();
    
  }
}

module.exports = Backendless.ServerCode.addType(OrderItem);

FindById

These events occur when a client application sends an API request to retrieve an object from the backend by its objectId.

Before create:

Backendless.ServerCode.Persistence.beforeFindById('table-name or *', function(req) {
  //add your code here
});

After create:

Backendless.ServerCode.Persistence.afterFindById('table-name or *', function(req) {
  //add your code here
});

where:

req.context- code runner context provides information about the application. For details see the CodeRunner™ Context topic.
req.itemId- objectId value of the object to retrieve. The value is assigned by Backendless to the object when it was initially saved..
req.relations- an optional array of relation names to pre-load when it is returned back to the client.

 - contains the result of the default implementation of the method. If the object is successfully loaded, the result is

req.result-  contains the result of the default implementation of the method. If object retrieval is successful, the result is the loaded object, otherwise if the invocation resulted in an error, it is available through the res.error property.

Example:
Generic handler - applies to all tables, except for the ones which have a dedicated event handler. A table-specific handler would use the @Asset annotation referencing the table name:

/* global Backendless */

/**
* @param {Object} req The request object contains information about the request
* @param {Object} req.context The execution context contains an information 
*                 about application, current user and event
* @param {Object} req.itemId 
* @param {string[]} req.relations 
*
* @returns {Object|Promise.<Object>|void} By returning a value you can stop 
*          further event propagation and return
*          a specific result to the caller
*/
Backendless.ServerCode.Persistence.beforeFindById('*', function(req) {
  //add your code here
});

LoadRelations

These events occur when a client application sends an API request to load related properties for an object.

 

Before loadRelations:After loadRelations:where:

 - code runner context provides information about the application and the client making the API call. For details see

 - the objectId value of the object to load. The value is assigned by Backendless to the object when it was initially saved.

 - the name of the table which contains the object identified by object_id.

relations- an array of relation names which identifies the related properties which should be loaded by the loadRelations call.

 - contains the result of the default implementation of the method. If the object is successfully loaded, the result contains

 

Example:
Generic handler - applies to all tables, except for the ones which have a dedicated event handler.A table-specific handler would use the @Asset annotation referencing the table name:

Remove

These events occur when a client application sends an API request to remove an object from the persistent storage.

 

Before remove:After remove:where:

 - code runner context provides information about the application and the client making the API call. For details see

 - the objectId value of the object to remove. The value is assigned by Backendless to the object when it was initially saved.

 - contains the result of the default implementation of the method. If the object is successfully removed, the result contains the timestamp when the deletion happened.

 

Example:
Generic handler - applies to all tables, except for the ones which have a dedicated event handler. A table-specific handler would use the @Asset annotation referencing the table name:

Update

These events occur when a client application sends an API request to update an existing object in the persistent storage.

Before update:After update:where:

 - code runner context provides information about the application and the client making the API call. For details see

 - contains the result of the default implementation of the method. If the object is successfully updated, the result contains the updated object.

Example:
Generic handler - applies to all tables, except for the ones which have a dedicated event handler. A table-specific handler would use the @Asset annotation referencing the table name. Additionally, the method signatures would use a class representing the table instead of the HashMap argument.

Describe

These events occur when a client application sends an API request to get a list of properties for a particular object type. This is conceptually identical to retrieving a list of columns in a data table.

Before describe:After describe:where:

 - code runner context provides information about the application and the client making the API call. For details see

 - the name of a data table to get a description for.

         -
Example:
Generic handler - applies to all tables, except for the ones which have a dedicated event handler. A table-specific handler would use the @Asset annotation referencing the table name:

Find

These events occur when a client application sends an API request to load a collection of objects. Optional search parameters may include loading related objects, sorting and/or paging options.

 

Before find:After find:where:

 - code runner context provides information about the application and the client making the API call. For details see

 - object containing search query, sorting, filtering or paging parameters.

 - contains the result of the default implementation of the method - an instance of BackendlessCollection. The collection contains

Example:
Generic handler - applies to all tables, except for the ones which have a dedicated event handler. A table-specific handler would use the @Asset annotation referencing the table name:

Find First

These events occur when a client application sends an API request to load the first the object in the collection. Optional search parameters may include options for pre-loading related objects and depth of the relations to pre-load.

Before find first:After find first:where:

 - code runner context provides information about the application and the client making the API call. For details see

 - contains the result of the default implementation of the method

Example:
Generic handler - applies to all tables, except for the ones which have a dedicated event handler. A table-specific handler would use the @Asset annotation referencing the table name:

Find Last

These events occur when a client application sends an API request to load the last the object in the collection. Optional search parameters may include options for pre-loading related objects and depth of the relations to pre-load.

Before find first:After find first:where:

 - code runner context provides information about the application and the client making the API call. For details see

 - contains the result of the default implementation of the method

Example:
Generic handler - applies to all tables, except for the ones which have a dedicated event handler. A table-specific handler would use the @Asset annotation referencing the table name

 


Please let us know how we can improve the documentation by leaving a comment. All technical questions should be posted to the Backendless Support forum. We do not respond to the technical questions on the documentation pages.: