Customizing cui.js Call Definitions

Cui.js decouples its own call-making logic from the call-definition logic. This allows the call definitions to track API versions as the APIs evolve, and an App to absorb these evolutions without requiring cui.js modifications. It also allows, on the contrary, call definitions to remain on fixed versions of the APIs, despite whatever API evolution occurs.

Cui.js distinguishes between these evergreen and static call definitions.

  • Evergreen call definitions guarantee your App will always use the latest versions of the APIs.
  • Static call definitions guarantee your App will always stay on the specified version of the APIs.

Evergreen Scenario

In most Apps, evergreen definitions are suitable. For example, an App that generally accesses Persons or Things would simply always want to use the latest versions of the APIs, without required an App rebuild or redeploy. This can be accomplished by using the asynchronous cui.api() call to load remote call definitions from the cui.js call definition server. In the following example, Idm and Iot call definitions are loaded into the App.

 cui.api({
    defs: [
        'https://cuijs.run.covisintrnd.com/defs/idm.json',
        'https://cuijs.run.covisintrnd.com/defs/iot.json'
    ],
    serviceUrl: 'PRD'
 }).then(function(obj) {
    .
    .
    .
 });

Each API family’s reference page shows it’s evergreen call definition URL.

The reference for the cui.api(options) call summarizes how to load evergreen definitions.

Static Scenarios

In other Apps, evergreen definitions can be problematic. For illustration purposes, consider a somewhat contrived example: an App that manages deployed Iot devices may wish to insulate itself from future API versions to guarantee those devices will always be manageable by the App.

Here are other general cases where static definitions also make sense:

  • When an older, fixed version of an API is required.
  • When a newer (unreleased) version of an API is required.
  • When a 3rd-party API is required.

For such scenarios, static call definitions must be 1) written by the App developer, and 2) explicitly loaded into cui.js.

1. Writing Static Definitions

Whether loaded remotely or locally, the anatomy of a call definition is the same. To see call definitions, click the ‘Defs’ tab (or the ‘Evergreen URL’) on each API family’s reference page. Here is what they look like:

[
  {
    "cmd": "activateDeviceTemplate",
    "call": "/devicetemplate/v1/deviceTemplates/{deviceTemplateId}/tasks/activate",
    "type": "POST",
    "accepts": "application/vnd.com.covisint.platform.deviceTemplate.v1+json",
    "contentType": "application/vnd.com.covisint.platform.deviceTemplate.v1+json"
  },
  {
    "cmd": "deactivateDeviceTemplate",
    "call": "/devicetemplate/v1/deviceTemplates/{deviceTemplateId}/tasks/deactivate",
    "type": "POST",
    "accepts": "application/vnd.com.covisint.platform.deviceTemplate.v1+json",
    "contentType": "application/vnd.com.covisint.platform.deviceTemplate.v1+json"
  },
  .
  .
  .
]

Note, the cui.js call definition object is comprised of discreet name/value pairs, and typically will include:

  1. cmd - The name for the cui.js method
  2. call - The API call URL (includes URI parameters inside curly brackets {})
  3. type - The API call RESTful action
  4. accepts - The API call media type
  5. contentType - The API call content type

The full detail for these and other properties is available in this comprehensive reference.

💡 Naming-conventions

cui.js commands are based on CRUD-terminology (Create, Update, Delete),
rather than RESTful-terminology (PUT, POST, etc.),

2. Loading Static definitions

Typically, Apps that depend on static definitions only require a discreet subset of the App functionality to be directed at a fixed version of an API. The majority of an App’s functionality is likely to be perfectly well-suited for evergreen calls.

This App will be based on evergreen call definitions, and then override a small subset of the calls with static definitions. In these cases, definitions will be loaded both remotely and locally. For example,

 cui.api({
    defs: [
      'https://cuijs.run.covisintrnd.com/defs/idm.json',
      [{
        cmd: 'activatePerson',
        call: '/person/v2/persons/tasks/activate',
        type: 'POST',
        accepts: 'application/vnd.com.covisint.platform.person.v1+json',
        contentType: 'application/vnd.com.covisint.platform.person.v1+json'            
      }]
    ],
    serviceUrl: 'PRD'
 }).then(function(obj) {
    .
    .
    .
 });

In this example, the Idm definitions are loaded remotely, and then a single call is overridden with a local definition that targets the v2 version of the Persons API.

Notice that the options.defs property takes an array, but the members of the array can be of two different types. Evergreen definitions are loaded via Strings (URLs in fact), and static definitions are loaded via Arrays of Objects.

If all of the definitions are static, then an App can choose to load cui.js synchronously.

Committing Static Definitions

When the static definitions describe newer versions of APIs which then become officially released, it is appropriate to commit those definitions to the cui.js server. Submit the new definitions by creating a Merge Request in the cui.js definitions repository.

Other than providing operationally correct calls, naming the commands is the most important part of the submitted definition. For consistency, the naming pattern is actionSubject, as in countOrganizations. The intent is for actions to be based on CRUD terminology. Commonly used actions are activate, create, count, deactivate, delete, get, and update.