oeCloud Example to demonstrate various Configurations of application Booting.

oeCloud example Application boot config is a way to understand concepts related to booting oeCloud with various configurations.

What you’ll build

oeCloud.io based application to demonstrate its various configuration and their behaviour during booting oeCloud.

What you’ll need:

  • You should have Node and NPM installed.

How to start with this guide

You can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you.

To start from the scratch go to Getting Started

Types of config files

The /server directory contains various config files that create application.

The standard files in this directory are:

  • config.json
  • datasources.json
  • middleware.json
  • model-config.json

config.json

Define application server-side settings in /server/config.json. For example here are the default settings that comes with any loopback application

    {
      "restApiRoot": "/api",
      "host": "0.0.0.0",
      "port": 3000,
      "legacyExplorer": false
    }

Apart from the above default settings ,app comes with someo eCloud specific configurations.

Property Default value Description
frameworkdsname db Used as the datasource associated with the “Framework Database”. An actual datasource with this name should exist in the application, either configured via datasources.json or via the DataSourceDefinition Model.
modelstocache - should be an String array of model names. The data saved using these models will be cached in memory upon access.
disablecaching false disables caching globally. To actually cache a Model , two requirements should be satisfied: 1) ‘disablecaching’ should be set to false 2) model should either be marked as cacheable by a ‘cacheable’: true property in its definition or model should be in the ‘modelstocache’ array
tenantsource USER The value of ’tenantsource’ can be one of QUERY, USERPROFILE, USER, REQUEST, HEADER, CALLCONTEXT, or CTX. This determines the place from where ’tenant ID’ will be fetched from.
tenantkey tenant_id The value of ’tenantkey’ determines the key within ’tenantsource’ whose value will be taken as the tenant ID.
disablenodered false Used to disables node-red
app oeCloud Application name
encryptionAlgorithm crypto.aes256 Encryption/Decryption Algorithm that will be used globally to encrypt properties of models. For this, model property should be tagged “encrypted” : true. Possible values: “crypto.aes256”,“crypto.aes-256-ctr”, “crypto.aes-256-cbc”,“aes128”, “aes192”
encryptionPassword - The password that will be used with the encryptionAlgorithm

To access the settings in application code, use app.get('property').

For further info on config.json and its default properties [click] (https://docs.strongloop.com/display/APIC/config.json)

Environment-specific settings

You can override values that are set in config.json in: config.local.js or config.local.json config.env.js or config.env.json, where env is the value of NODE_ENV (typically development or production); so, for example config.production.json.

The {env} specific settings are applicable to all other types of config files as well.

datasources.json

Configure data sources in /server/datasources.json. You can set up as many data sources as you want in this file.

For example

    {
      "db": {
        "name": "db",
        "connector": "memory"
      },
      "myDB": {
        "name": "myDB",
        "connector": "mongodb",
        "url": "mongodb: localhost:27017/db",
    	"database": "commonDB",
    	"password": "admin",
    	"name": "commonDB",
    	"user": "admin",
    	"connectionTimeout": 50000
      }
    }

Each connector has some connector level properties.

To access data sources in application code, use app.datasources.datasourceName.

middleware.json

Used to Set up middlewares in application.

Here is the default version created by the Application.

    {
      "initial:before": {
        "loopback#favicon": {}
      },
      "initial": {
        "compression": {},
        "cors": {
          "params": {
            "origin": true,
            "credentials": true,
            "maxAge": 86400
          }
        }
      },
      "session": {},
      "auth": {},
      "parse": {},
      "routes": {
        "loopback#rest": {
          "paths": [
            "${restApiRoot}"
          ]
        }
      },
      "files": {
        "loopback#static": {
          "params": "$!../client"
        }
      },
      "final": {
        "loopback#urlNotFound": {}
      },
      "final:after": {
        "loopback#errorHandler": {}
      }
    }

Each top-level property in middleware.json corresponds to one of the following middleware phases:

Phase Description
initial The first point at which middleware can run.
session Prepare the session object.
auth Handle authentication and authorization.
parse Parse the request body.
routes HTTP routes implementing your application logic. Middleware registered via the Express API app.use, app.route, app.get (and other HTTP verbs) runs at the beginning of this phase. Use this phase also for sub-apps like loopback/server/middleware/rest or loopback-explorer.
files Serve static assets (requests hit the file system here).
final Deal with errors and requests for unknown URLs.

phase is one of the predefined phases listed above (initial, session, auth, and so on) . sub-phase (optional) can be before or after.

Each phase has “before” and “after” subphases in addition to the main phase, encoded following the phase name, separated by a colon.

For example, for the “initial” phase, middleware executes in this order:

initial:before 
initial
initial:after

For further info on phases please follow

Note : You can even add your own custom phase. Follow the link on how to add custom phases.

model-config.json

The file /server/model-config.json configures LoopBack models, for example it binds models to data sources and specifies whether a model is exposed over REST.

Top-level properties

Property Type Description
_meta.sources Array Array of relative paths to custom model definitions. By default, LoopBack applications load models from /common/models subdirectory. To specify a different location (or even multiple locations) use the _meta.sources property, whose value is an array of directory paths.
_meta.mixins Array Array of relative paths to custom mixin definitions. See Defining mixins for more information.
modelName String Name of a model, either a built-in model or a custom model defined in the _meta.sources folder.

Model properties

Property Type Description
datasource String Name of the data source to which the model is connected. Must correspond to a data source defined in datasources.json.
public Boolean Whether the model API is exposed. If true, then the model is exposed over REST. Does not affect accessibility of Node API.

For further info

component-config.json

LoopBack components are predefined packages that extend a basic LoopBack application. Fundamentally, a component is related code bundled together as a unit to enable LoopBack applications to easily reuse it. They are registered to the app using component-config.json.

An application will load all components that have an entry in the component-config.json that does not evaluate to false. If the component is installed using npm, use its package name as the key; if the component is a local component, specify its relative path from the server directory. Here is an example of a component-config.json file with entries for a component installed via npm, and the local components.

    {
      "loopback-component-explorer": {
        "mountPath": "/explorer"
      },
      "./components/my-component": {
        "path": "/my-component"
      },
      "./components/show-options": {},
      "./components/version": true
    }

Application booting process

The application is initialized from an options object or a set of JSON and JavaScript files. The Booting of application starts when we call the boot function in server.js which internally calls the following loopbackback function

bootLoopBackApp(app, options, callback){
...
}

This function takes an optional argument options that is either a string or an object.

If the options is a string, then it sets the application root directory based on the string value. Then it:

  1. Creates DataSources from the datasources.json file in the application root directory.
  2. Configures Models from the model-config.json file in the application root directory.
  3. Configures the LoopBack Application object from the config.json file in the application root directory.

If the options is an object, then it looks for models, dataSources,config, modelsRootDir, dsRootDir, appConfigRootDir and appRootDir properties of the object. If the object has no appRootDir property then it sets the current working directory as the application root directory.

The execution environment, {env} , is established from, in order,

  • options.env
  • process.env.NODE_ENV,
  • the literal development.

Then it:

  1. Creates DataSources from the options.dataSources object, if provided;

    otherwise, it searches for the files

    • datasources.json,
    • datasources.local.js or datasources.local.json (only one),
    • datasources.{env}.js or datasources.{env}.json (only one)

    in the directory designated by ‘options.dsRootDir’, if present, or the application root directory. It merges the data source definitions from the files found.

  2. Creates Models from the options.models object, if provided;

    otherwise, it searches for the files

    • model-config.json,
    • model-config.local.js or model-config.local.json (only one),
    • model-config.{env}.js or model-config.{env}.json (only one)

    in the directory designated by ‘options.modelsRootDir’, if present, or the application root directory. It merges the model definitions from the files found.

  3. Configures the Application object from the options.config object, if provided;

    otherwise, it searches for the files

    • config.json,
    • config.local.js or config.local.json (only one),
    • config.{env}.js or config.{env}.json (only one)

    in the directory designated by ‘options.appConfigRootDir’, if present, or the application root directory. It merges the properties from the files found.

  4. Configures the Application object from the options.middleware object, if provided;

    otherwise, it searches for the files

    • middleware.json,
    • middleware.local.js or middleware.local.json (only one),
    • middleware.{env}.js or middleware.{env}.json (only one)

    in the directory designated by ‘options.appConfigRootDir’, if present, or the application root directory. It merges the properties from the files found.

  5. Configures the Application object from the options.components object, if provided;

    otherwise, it searches for the files

    • component-config.json,
    • component-config.local.js or component-config.local.json (only one),
    • component-config.{env}.js or component-config.{env}.json (only one)

    in the directory designated by ‘options.appConfigRootDir’, if present, or the application root directory. It merges the properties from the files found.

In both cases, the function loads JavaScript files in the /boot subdirectory of the application root directory with require().

Once All the config and boot files are loaded from this app, the application will fetch boot files from oeCloud and adds to options.bootDirs. and mixins to options.mixinDirs.

Then it:

  1. Creates DataSources from the files

    • datasources.{env}.js or datasources.{env}.json (only one) or
    • datasources.local.js or datasources.local.json (only one) or
    • datasources.json

    in the directory designated by ‘options.dsRootDir’, if present, or the application root directory. Then merges the current config file with oeCloud’s final datasources object taking oeCloud’s datasources content as priority.

    NOTE: During merge the values of a particular key are completely replaced with the new values in oeCloud’s datasources if any matching key is found. Finally the merged object is attached to options.dataSources.

  2. Creates model-config from the files

    • model-config.{env}.js or model-config.{env}.json (only one) or
    • model-config.local.js or model-config.local.json (only one) or
    • model-config.json

    in the directory designated by ‘options.dsRootDir’, if present, or the application root directory. Then merges the current model-config file with oeCloud’s final model-config object taking oeCloud’s model-config content as priority. Finally the merged object is attached to options.models.

  3. Creates config from the files

    • config.{env}.js or config.{env}.json (only one) or
    • config.local.js or config.local.json (only one) or
    • config.json

    in the directory designated by ‘options.dsRootDir’, if present, or the application root directory. Then merges the current config file with oeCloud’s final config object taking oeCloud’s config content as priority. Finally the merged object is attached to options.config.

  4. Creates middleware from the files

    • middleware.{env}.js or middleware.{env}.json (only one) or
    • middleware.local.js or middleware.local.json (only one) or
    • middleware.json

    in the directory designated by ‘options.dsRootDir’, if present, or the application root directory. Then merges the current config file with oeCloud’s final middleware object taking oeCloud’s middleware content as priority.

    NOTE: The merge of middleware happens in phases as defined in the middleware.json file. Finally the merged object is attached to options.middleware.

  5. Creates component-config from the files

    • component-config.{env}.js or component-config.{env}.json (only one) or
    • component-config.local.js or component-config.local.json (only one) or
    • component-config.json

    in the directory designated by ‘options.dsRootDir’, if present, or the application root directory. Then merges the current config file with oeCloud’s final component-config object taking oeCloud’s component-config content as priority.

    Finally the merged object is attached to options.components.

Setting up env variable for this guide.

There are many ways to set env variable depending on platform and IDE.

  • using terminal $ NODE_ENV=test node .
  • Using PowerShell
>$env:NODE_ENV="test"
>node .
or 
>($env:NODE_ENV="test") -and (node .)
  • Using cmd
>set NODE_ENV=test
>node .
or
>set NODE_ENV=test&&node .

working with config.json file

  1. Changing config.json

    • Open config.json file from application-boot\server folder.
    • change the value of the property port from 3000 to 5000.
    • now restart the server and open browser link

    You will observe that the browser link localhost:3000/explorer does not work. Now open browser link [localhost:5000/explorer] (http://localhost:5000/explorer)

  2. Adding new config file

    • Create a new file config.test.json in application\server folder.
    • add the below json and save the file.
    {
    "port": 8080
    }
    
    • Restart the server again with env = test

    Now you will notice that the port is again changed to 8080.

working with model-config.json file

  1. Adding new model-config.json

    • Create a new file model-config.test.json in application-boot\server folder.
    • add the below json and save the file.
        {
             "Country": {
                "dataSource": "appdb",
                "public": false
            }
        }
    
    • Restart the server with env = test.

    Now you will notice that the Country model is not available.

Likewise you can play around with various config files to understand the concepts.

Summary

Congratulations!! You have successfully learnt various config settings based on oeCloud.