Configuration API for Front-end Applications (CAFA)

November 3, 2022


This is a REST API for storing and retrieving configuration settings — primarily for frontend applications.

Usage

To find the endpoint specific for your account, use the "getServiceEndpoints" call. A few sample endpoints are given below, but this is not a complete list.

Each endpoint also has a Swagger documentation page.

DatacenterAPI endpointDocumentation page
Sandboxhttps://api-cafa-eu10.erply.com/https://api-cafa-eu10.erply.com/documentation/index.html
Americahttps://api-cafa-us.erply.com/https://api-cafa-us.erply.com/documentation/index.html
Europehttps://api-cafa-eu.erply.com/https://api-cafa-eu.erply.com/documentation/index.html
Australia and Southeast Asiahttps://api-cafa-au.erply.com/https://api-cafa-au.erply.com/documentation/index.html

Use an Erply client code and API session key to make requests. (Send these as headers "clientCode" and "sessionKey".)

Seeing and editing CAFA settings

In back office, if your account has the newer menu bar, you can see all CAFA settings at “Settings” > “Configuration Admin”.

If you do not have this item listed in the menu, you can alternatively go to the following URL:

https://conf-admin-ui.erply.com/?clientCode=<your account number>

Data structure

Each record in CAFA has the following properties:

  • application — This identifies the application that reads and writes the configuration. 
  • level — This can have four values: Company (the setting applies to the whole Erply account) , Warehouse (the setting is location-specific), Pos (the setting is register-specific), or User (this is a user's preference).
  • level_id —You need to populate this field if you set the level to Warehouse (it must indicate location ID), Pos (it must indicate register ID) or User (it must indicate user ID).
  • name — Name of the setting.
  • type — An optional field for grouping related settings together. If not needed, leave it empty.
  • value — Content of the setting. CAFA lets you store an arbitrary string, but we strongly recommend to stick to two options: either a plain numeric or text value (for example 42 or store123), or preferably a JSON structure.

Each record also has an ID, and you might sometimes need to know it when editing a record. But the combination of application + level + level_id + name + type is unique, so a setting can always be looked up using these five parameters, too.

It is possible to make the configuration layered, although this is not required. “Layering” means that if you introduce a property that can be configured per-location, and store it as "level": "Warehouse", "level_id": "<location ID>", you can optionally have a default fallback setting at Company level, too. If you query the API with header Look-Deeper: true, and there is no configuration for that particular location, API will return the fallback.

Storing data in JSON format

JSON is preferable to plain text and numeric values, but we advise to follow two principles when storing JSON.

1. Keep the values small

Store your configuration as many small values, rather than one big value. Do not create a huge JSON structure that contains the whole configuration of your app.

An ideal CAFA setting is a flat JSON object with a small number of fields:

{
  "hostName": "example.org",
  "port": "9999"
}

The primary reason is to prevent accidental overwrites and race conditions. Having a big JSON increases the possibility that two API requests want to modify different parts of the configuration at the same time, and end up overwriting each others' changes.

Small atomic values also work better with the "layered configuration" that was suggested above.  

2. Do not use arrays of records

This is important because individual fields inside that JSON must be addressable with JSONPath queries. (Some Erply tools rely on that.) 

As an example, if you store a list of payment methods as the following JSON:

(RECOMMENDED:)

{
  "creditCard": {"label": "Credit Card"},
  "debitCard": {"label": "Debit Card"},
  "giftCard": {"label": "Gift Certificate"}
}

Then the label for credit card payments can be trivially addressed in JSONPath as $.creditCard.label.

In contrast, if you opt for the following structure instead:

(DO NOT USE!)

[
  {"name": "creditCard", "label": "Credit Card"},
  {"name": "debitCard", "label": "Debit Card"},
  {"name": "giftCard", "label": "Gift Certificate"}
]

then there is no way to address the field with JSONPath at all! $[0].label might not work, because presumably the order of elements in the array (and their number) is not fixed and can shift around if elements are added or removed.

Or another way to put it: please avoid using a CAFA record as a database table.