Using models with LoopBack connectors

Interactions between the LoopBackRequest node and some types of backend data source require LoopBack® models to be defined.

Some LoopBack connectors require that the data model to be interacted with is defined through a LoopBack JSON model. When the LoopBackRequest node interacts for the first time with a named LoopBack object (which is either specified as a node property or dynamically overridden in the local environment), it looks for a LoopBack JSON model file in a subdirectory of the directory that contains the datasources.json file. For information about configuring the model, see Configuring the data source and models for your LoopBack connector.

A LoopBack model is typically required for data sources that are backed by relational databases, where table objects with a rigid data structure are used. With these types of data source, the model can be used to define property mappings between the database columns and the LoopBack properties that are used by the LoopBackRequest node.

In the following example, the integration node called IIB10 uses a datasources.json file that is located in the MQSI_WORKPATH\IIB10\connectors\loopback directory, where MQSI_WORKPATH is defined by the MQSI_WORKPATH environment variable. The datasources.json file includes the following stanza, called POSTGRESQL, to connect to the PostgreSQL database:
"POSTGRESQL": {
    "host": "localhost",
    "port": 5432,
    "database": "loopback",
    "name": "postgreSQL",
    "connector": "postgresql"
  }

The product.json file is copied into the MQSI_WORKPATH\IIB10\connectors\loopback\POSTGRESQL directory. For the LoopBackRequest node to use the model, the LoopBack object property on the node (or the LocalEnvironment.Destination.Loopback.Request.object variable, if used) must match exactly the name of the model, excluding the .json file extension. Typically, these names are the same, but they can be different; for example, if the name of the object in the LoopBack connected system contains a character that would be invalid in a file name. If the names are different, a BIP3880 message is issued.

In this case, the LoopBack object property is configured as shown in the following diagram:
This diagram shows the LoopBack object property in the Basic tab of the LoopBackRequest node.
The following example shows how to use a LoopBack model to interact with a product table that is defined in a PostgreSQL database:
CREATE TABLE public.product
(
  product_id serial NOT NULL,
  product_name character varying(20),
  sell_by date,
  number_in_stock integer,
  obsolete boolean,
  CONSTRAINT product_pk PRIMARY KEY (product_id)
)
The LoopBack PostgreSQL connector supports discovery, so the StrongLoop® and API Connect model-generation tools were used to generate the following LoopBack model for the product table. This model was output to the product.json file:
{
  "name": "Product",
  "base": "PersistedModel",
  "idInjection": false,
  "options": {
    "validateUpsert": true
  },
  "postgresql": {
    "schema": "public",
    "table": "product"
  },
  "properties": {
    "numberInStock": {
      "type": "number",
      "required": false,
      "length": null,
      "precision": 32,
      "scale": 0,
      "postgresql": {
        "columnName": "number_in_stock",
        "dataType": "integer",
        "dataLength": null,
        "dataPrecision": 32,
        "dataScale": 0,
        "nullable": "YES"
      },
      "_selectable": true,
      "comments": "Items in stock"
    },
    "obsolete": {
      "type": "boolean",
      "required": false,
      "length": null,
      "precision": null,
      "scale": null,
      "postgresql": {
        "columnName": "obsolete",
        "dataType": "boolean",
        "dataLength": null,
        "dataPrecision": null,
        "dataScale": null,
        "nullable": "YES"
      },
      "_selectable": true,
      "comments": "Flag if stock is obsolete"
    },
    "productId": {
      "type": "number",
      "id": true,
      "required": true,
      "length": null,
      "precision": 32,
      "scale": 0,
      "postgresql": {
        "columnName": "product_id",
        "dataType": "integer",
        "dataLength": null,
        "dataPrecision": 32,
        "dataScale": 0,
        "nullable": "NO"
      },
      "_selectable": false,
      "comments": "Unique product number"
    },
    "productName": {
      "type": "string",
      "required": true,
      "length": 20,
      "precision": null,
      "scale": null,
      "postgresql": {
        "columnName": "product_name",
        "dataType": "character varying",
        "dataLength": 20,
        "dataPrecision": null,
        "dataScale": null,
        "nullable": "YES"
      },
      "_selectable": true,
      "comments": "Description of product"
    },
    "sellBy": {
      "type": "date",
      "required": false,
      "length": null,
      "precision": null,
      "scale": null,
      "postgresql": {
        "columnName": "sell_by",
        "dataType": "date",
        "dataLength": null,
        "dataPrecision": null,
        "dataScale": null,
        "nullable": "YES"
      },
      "_selectable": true,
      "comments": "Expiry date"
    }
  },
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": {}
}

For more information about the StrongLoop and API Connect model-generation tools, see the documentation on the StrongLoop website.

In the PostgreSQL product table, the product_id column is defined with a data type of serial, which results in values for the column being generated automatically when a row is inserted into the table. To reflect this, the LoopBack product.json model has been updated to include a generated property for the productId. The required attribute has also been changed to false, which stops the model checking that the data in requests sent from the LoopBackRequest node includes a productId when a row is created, because this value will be generated automatically. The updated model is shown in the following example:
"productId": {
      "type": "number",
      "id": true,
      "required": false,
      "generated": true,
      "length": null,
      "precision": 32,
      "scale": 0,
      "postgresql": {
        "columnName": "product_id",
        "dataType": "integer",
        "dataLength": null,
        "dataPrecision": 32,
        "dataScale": 0,
        "nullable": "NO"
      },
      "_selectable": false,
      "comments": "Unique product number"
    }
The model can also be used to set default values for data values; in the following example, the obsolete value defaults to false:
"obsolete": {
      "type": "boolean",
      "required": false,
      "default": false,
      "length": null,
      "precision": null,