Toggle menu

Configuration End Points

We've developed a standard pattern of end points that are used to hold environment specific configuration for each of our products and solutions.


When you're developing a solution it's best practice to hold environment configuration separately, away from the solution's main end points.

End Point Configuration Structure
¬†Holding configuration separately allows end points to be easily exported from one iCM to another, allows the configuration end points to be secured to appropriate iCM users, and means they can be flagged securely as "internal".

Our standard configuration structure for named solutions is config.environment.solutionName.getConfig (see the screenshot of the end point groups).

The root config group contains two additional end points:

  • config.getContextName - returns the environment we are working in, which will match the "dev", "live" or "test" group names that hold our solution's configuration
  • config.getConfig - the end point that our solution (either our forms, workflows or other end points) will call to get the configuration it needs


TimsSolution in the screenshot above has two sets of configuration, one for dev and one for live.

An end point in TimsSolution that needs configuration values, no matter what the environment,  can call:

let config = this.invokeEP("config.getConfig", {"application":"TimsSolution" });

The call provides the name of the solution we need the configuration for (ie, its own name) as a parameter which gets passed to the config.getConfig end point. Note how there is no need to provide any environmental information, meaning the end point will be identical wherever it is deployed.

The config.getConfig end point looks like this. Note how it also uses invokeEP to call the getContextName end point:

function(params, credentials) {
    let contextName = params.contextOverride || this.invokeEP( ".getContextName" );
    let configFnName = "." + contextName + "." + params.application + ".getConfig";
    let confObj;
    try {
        return this.invokeEP( configFnName );
    catch ( ex ) {
        throw new Error( "Unable to find configuration for application: [" + params.application + "] in environment: [" + contextName + "] " + configFnName );

And the config.getContextName end point uses this.config.env to work out which environment we are in, based upon the site's enterprise URL:

function(params, credentials) {
    var env;
        case "http://mydevsite/enterprise/icm":
            env = "dev";
        case "":
            env = "live";
            env = "QA";
    return env;

Other methods could be used to work out the environment, like checking the siteName returned form the same this.conf.env. This should be decided upon when the config.getContextName is first created.

Our end point holds some information about various template and article IDs and an API Key relevant to this iCM installation:

function(params, credentials) {
    return {
        "apiKey" : "3E100846-2A72-4AA6-B9A7-DD1DDF6E80D2",
        "rootArticleID" : 781,
        "templateID": 29

This configuration end point is the only end point that would need to be edited when the solution is deployed into a new environment.

Finally, if we go back to the start and look at the original end point that needed the configuration, we're asking for the apiKey:

function(params, credentials) {
    var config = this.invokeEP("config.getConfig",  {"application" : "TimsSolution" })
    return config.apiKey;

Which returns:

    "jsonrpc": "2.0",
    "id": 555,
    "result": "3E100846-2A72-4AA6-B9A7-DD1DDF6E80D2"

Next Steps

The example above demonstrates how layers of end points can be constructed to hold configuration.

This same principle is used in many of our solution to create a layer of end points to handle database transactions, another for API Server worker interactions, and a top layer of end points called from forms and workflow processes.

We'll look at examples of these layers of end points in a future article examining architecture and integration.

Last modified on July 31, 2023

Share this page

Facebook icon Twitter icon email icon


print icon