Skip to content

User AddIn and Function

VinceZK edited this page Apr 4, 2020 · 3 revisions

The provided endpoints are still not enough if we put them in real use cases. We always need more business level validations, substitutions, and enrichment. For example, we need run a permission check before the change is made to an instance. Or we need enrich some information which can be auto derived, like changed-by, changed time, and so on. Another more specific example in accounting is to auto generate tax line items when posting an invoice.

With such kinds of specific logic, a framework can hardly do everything for you. However, a good framework can help you focus on writing your domain specific logic. That is to say, you don't need to care about or worry about how the data is persisted, how the incoming requests are routed, and how the security is ensured.

User AddIn

User AddIn allows you to enhance existing business logic. However, you can only add your logic in predefined call-points.

In the following example, the function 'getEntityInstance' is registered to the User AddIn 'afterEntityCreation'. Then, after an entity instance is created, it will be read from the DB and returned to the UI.

afterEntityCreation.use('*', getEntityInstance);

function getEntityInstance(req, callback) {
  entity.getInstanceByGUID(req.body['INSTANCE_GUID'], function (err, instance){
    if(err) callback(err); 
    else {
      req.body = instance; // Pass the instance to the next addIn function
      callback(null, instance);
    }
  })
}

A User AddIn function has 2 parameters: the first one is the http request object passed from ExpressJS, and the second one is a callback function. You can register an AddIn function under a topic. Thus, only the requests that belong to the topic will invoke the AddIn function. If you register it under the topic '*', then all the requests will invoke the function.

By default, following User AddIns are defined by Json-on-Relations:

  1. beforeEntityCreation: Use this AddIn to add logic before creating an entity instance.
  2. beforeEntityChanging: Use this AddIn to add logic before changing an entity instance.
  3. beforeEntityQuery: Use this AddIn to add logic before query entity instances.
  4. beforeMetaReading: Use this AddIn to add logic before reading entity meta data.
  5. beforeModelProcessing: Use this AddIn add logic before processing models.
  6. afterEntityCreation: Use this AddIn to add logic after an entity instance is created.
  7. afterEntityChanging: Use this AddIn to add logic after an entity instance is changed.
  8. afterEntityReading: Use this AddIn to add logic after an entity instance is read.

User Function

With User Function, you can implement arbitrary business logic in server side.

A User Function has 3 parameters, with the first one 'input' referring to the req.body get from ExpressJS. The second parameter is 'user' which points the user session context get from PassportJS. The third one is a callback function for the returned value which will be read by the client.

Below gives an simple example:

const userFunction = require('./server/models/userFunction');

userFunction.register('testFunction', function (input, user, callback) {
  callback(null, 'The input is ' + input.data + '. The user session is ' + user);
});

Then, this function can be invoked as following:

POST http://localhost:3000/api/function/testFunction
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{"data": "Hello World"}

The return should be:

"The input is Hello World. The user session is undefined"