Home > Help center > AppCell > AppCell Installation files

AppCell Installation files

This article will detail the four core installation (a.k.a. configuration) files of the ApiHawk application packaging standard software AppCell, which together perform the action of installing a Cell onto the destination Appcell server. For more information on how AppCell operates please see this article.

The five installation files of AppCell include:

  1. Appcell.json - basic information for the Cell;
  2. Plugin.json - information for the final Plugin configuration;
  3. Resources.json - all Resources the Cell supports;
  4. Settings.json - information on the main software of the product configuration; includes all options and fields in the payload.
  5. Ui.json - information on the configuration of the UI portion of the process.

Key $payload vs. key payload

It is important to first know the syntax difference between $payload and payload, where only the “$” sign is the varying factor.

In the JSON installation data below, there are “payload” keys included. These can have their values set in two different ways: a) by presenting them as a URL, or b) by including the full information of the payload.

By setting the key “payload” as $payload, this means its value will be presented as a URL, which can lead to the complete payload information. This is done for convenience and better structure of the entire JSON file.

Example:

{ 
   "resources":{ 
      "Domain":{ 
         "identifier":"domain",
         "$payload":"https://repository.appcell.io/newresellerclubcell/schema/domain/register.schema.json",
         "$result":"https://repository.appcell.io/newresellerclubcell/schema/domain/domain.schema.json",
         "rest":[ 
            "create",
            "fetch",
            "update"
         ]
      }
   }
}

By setting the key “payload” as payload only, this means its value will be presented as the complete payload information.

Example:

{ 
   "resources":{ 
      "Domain":{ 
         "identifier":"domain",
         "payload":"",
         "definitions":[ 

         ],
         "$schema":"http:\/\/json-schema.org\/draft-07\/schema#",
         "$id":"http:\/\/example.com\/root.json",
         "type":"object",
         "title":"The Root Schema",
         "required":[ 
            "domain",
            "ns1",
            "ns2",
            "ns3",
            "ns4"
         ],
         "properties":{ 
            "domain":{ 
               "$id":"#\/properties\/domain",
               "type":"string",
               "title":"The Domain Schema",
               "default":"",
               "examples":[ 
                  "{{product.option.domain}}"
               ],
               "pattern":"^(.*)$"
            },
            "ns1":{ 
               "$id":"#\/properties\/ns1",
               "type":"string",
               "title":"The Ns1 Schema",
               "default":"",
               "examples":[ 
                  "ns1.icnanycast.com"
               ],
               "pattern":"^(.*)$"
            },
            "ns2":{ 
               "$id":"#\/properties\/ns2",
               "type":"string",
               "title":"The Ns2 Schema",
               "default":"",
               "examples":[ 
                  "ns2.icnanycast.com"
               ],
               "pattern":"^(.*)$"
            },
            "ns3":{ 
               "$id":"#\/properties\/ns3",
               "type":"string",
               "title":"The Ns3 Schema",
               "default":"",
               "examples":[ 
                  "{{product.option.ns3}}"
               ],
               "pattern":"^(.*)$"
            },
            "ns4":{ 
               "$id":"#\/properties\/ns4",
               "type":"string",
               "title":"The Ns4 Schema",
               "default":"",
               "examples":[ 
                  "{{product.option.ns4}}"
               ],
               "pattern":"^(.*)$"
            }
         }
      }
   },
   "$result":"https://repository.appcell.io/newresellerclubcell/schema/domain/domain.schema.json",
   "rest":[ 
      "create",
      "fetch",
      "update"
   ]
}

The same logic follows $result and result.

AppCell.json

This file represents the basic information on the Cell.

The Cell is a micro-software developed to connect a third-party vendor to standardized AppCell actions. Cells are combined to work together in hybrid plugins. A cell It will translate Billia/AppCell commands to vendor-specific business logic. The cell has very specific to its purpose resources, where it ships all of them for the necessary task. At the same time one Cell can preconfigure multiple Plugins by providing its own logic.

Below is an example AppCell.json file:

{ 
   "name":"newResellerClubCell",
   "description":"",
   "license":"BSD-3-Clause",
   "type":"plugin",
   "support":{ 
      "email":"thehawks@apihawk.com"
   },
   "homepage":"https://www.apihawk.com/",
   "config":[ 

   ],
   "require":{ 
      "appcell":">=1",
      "ui":"^1.0",
      "etcd": ">=3.0"
   }
}

Properties

name

Displays the name of the Cell which needs to be set in camelCase and must end with “-cell”. It is recommended that the name doesn't include non-alphanumeric characters or white spaces.

Example:

{ 
   "name":"newResellerClubCell"
}

description

Displays information and a description of the plugin and its function.

Example:

{ 
   "description":"plugin"
}

license

Describes the license of the Cell. This can be either a string or an array of strings.

Most common licenses include:

  • Apache-2.0;
  • BSD-2-Clause;
  • BSD-3-Clause;
  • BSD-4-Clause;
  • GPL-2.0-only / GPL-2.0-or-later;
  • GPL-3.0-only / GPL-3.0-or-later;
  • LGPL-2.1-only / LGPL-2.1-or-later;
  • LGPL-3.0-only / LGPL-3.0-or-later;
  • MIT.

More licenses are listed in SPDX Open Source License Registry.

Example:

{ 
   "license":"Apache-2.0"
}

When there is a choice between licenses, multiple ones can be specified in an array.

Example:

{ 
   "license":[ 
      "BSD-2-Clause",
      "BSD-3-Clause"
   ]
}

They could also be separated with "or" enclosed in parenthesis.

Example:

{ 
   "license":"(BSD-2-Clause or BSD-3-Clause)"
}

Following the same logic, when many licenses need to be included, they have to be separated with “and”enclosed in parenthesis.

Example:

{ 
   "license":"(BSD-2-Clause and BSD-3-Clause and BSD-4-Clause)"
}

type

Describes the type of the cell. Currently supports only plugin.

Example:

{ 
   "type":"plugin"
}

support

Depending on the business, describes a chosen Support contact or information through various channels.

The Support channels that can be used include:

  • email: Email address for support.
  • issues: URL to the issue tracker.
  • forum: URL to the forum.
  • wiki: URL to the wiki.
  • irc: IRC channel for support, as irc://server/channel.
  • source: URL to browse or download the sources.
  • docs: URL to the documentation.
  • rss: URL to the RSS feed.
  • chat: URL to the chat channel.

Example:

{ 
   "support":{ 
      "email":"thehawks@apihawk.com"
   }
}

homepage

Describes an optional key-value pair for the website of the business.

Example:

{ 
   "homepage":"https://www.apihawk.com/"
}

config

Describes any optional additional configurations that can be set in the JSON file.

Example:

{ 
   "config":[ 
      "ConfigCustom",
      "ConfigNew"
   ]
}

require

Describes requirements needed for the Cell, in this case - the minimum required versions of AppCell, the UI and the etcd storage.

The “version” itself represents a specific known set of files which when changed (updated), the version numerically moves along, as well. A version range may be presented by using operators >, >=, <, <=, !=. А Caret Version Range can also be used with operator ^ where early releases which contain known threats are excluded from the versions range, while still benefiting from all new backward compatible releases.

Example:

{ 
   "require":{ 
      "appcell":">=1",
      "ui":"^1.0",
      "etcd": ">=3.0"
   }
}

etcd

When “etcd” is present for the “required” field, it means that during the installation of the plugin, the system will provide an etcd storage for that cell, along with login information and specific permissions.

To see more information on the “etcd” functionality, please see this article.

Example:

{ 
   "appcell":{ 
      "etcd":{ 
         "username":"examplecell",
         "password":"L8bw8BS7jcpkmF1t",
         "access":"/examplecell/*"
      }
   }
}

Plugin.json

This file defines all Plugins that the Cells ships. The Plugin is an abstract configuration of required workers and actions, which it executes. It comprises one or more Cells as per the purpose it follows. The Plugin defines the business logic of the company and is used for communication with external software.

Plugins have two main functionalities: implement and actions.

Implement defines all schemas that the Plugin implements, i.e. what obligatory functionalities it must possess. E.g. - if it implements “availability”, this means it must possess checkAvailability as a functionality. Please see more information on schemas here.

Example:

{ 
   "plugin":{ 
      "NewResellerClub":{ 
         "implements":[ 
            "https://repository.appcell.io/core/service.schema",
            "https://repository.appcell.io/core/availability.schema",
            "https://repository.appcell.io/core/renewable.schema"
         ]
      }
   }
}

The schemas listed under the implements key help AppCell to validate that all stated functionalities will be/are present and available.

Actions define various action types that depend on the schemas implemented. For every action, multiple executions in the Cell can be made.

Example:

{ 
   "actions":{ 
      "create":[ 
         { 
            "resource":"Domain",
            "action":"create",
            "$payload":"https://repository.appcell.io/newresellerclubcell/schema/domain/register.payload.json",
            "$result":"https://repository.appcell.io/newresellerclubcell/schema/domain/domain.result.json"
         }
      ]
   }
}

Below is an example Plugin.json file:

{
  "plugin": {
    "NewResellerClub": {
      "implements": [
        "https://repository.appcell.io/core/service.schema",
        "https://repository.appcell.io/core/availability.schema",
        "https://repository.appcell.io/core/renewable.schema"
      ],
      "actions": {
        "create": [
          {
            "resource": "Domain",
            "action": "create",
            "$payload": "https://repository.appcell.io/newresellerclubcell/schema/domain/register.payload.json",
            "$result": "https://repository.appcell.io/newresellerclubcell/schema/domain/domain.result.json"
          }
        ],
        "fetch": [
          {
            "resource": "Domain",
            "action": "fetch",
            "$payload": "https://repository.appcell.io/newresellerclubcell/schema/domain/domain.payload.json",
            "$result": "https://repository.appcell.io/newresellerclubcell/schema/domain/domain.result.json"
          }
        ],
        "update": [
          {
            "resource": "Domain",
            "action": "update",
            "$payload": "https://repository.appcell.io/newresellerclubcell/schema/domain/domain.payload.json",
            "$result": "https://repository.appcell.io/newresellerclubcell/schema/domain/domain.result.json"
          }
        ],
        "checkAvailability": [
          {
            "resource": "Domain",
            "action": "checkAvailability",
            "security": "public",
            "$payload": "https://repository.appcell.io/newresellerclubcell/schema/domain/checkAvailability.payload.json",
            "$result": "https://repository.appcell.io/newresellerclubcell/schema/domain/checkAvailability.result.json"
          }
        ],
        "transfer": [
          {
            "resource": "Domain",
            "action": "transfer",
            "$payload": "https://repository.appcell.io/newresellerclubcell/schema/domain/transfer.payload.json",
            "$result": "https://repository.appcell.io/newresellerclubcell/schema/domain/domain.result.json"
          }
        ],
        "synchronize": [
          {
            "resource": "Domain",
            "action": "synchronize",
            "$payload": "https://repository.appcell.io/newresellerclubcell/schema/domain/domain.payload.json",
            "$postpayload": "https://repository.appcell.io/newresellerclubcell/schema/domain/synchronize.postpayload.json"
          }
        ],
        "renew": [
          {
            "resource": "Domain",
            "$payload": "https://repository.appcell.io/newresellerclubcell/schema/domain/renew.payload.json",
            "action": "renew"
          }
        ],
        "getEppCode": [
          {
            "resource": "Domain",
            "$payload": "https://repository.appcell.io/newresellerclubcell/schema/domain/domain.payload.json",
            "action": "getEppCode",
            "postpayload": {
              "data": {
                "auth_info": "{{result}}"
              },
              "type": "overwrite"
            }
          }
        ],
        "fetchAll.Contact": [
          {
            "resource": "Contact",
            "action": "fetchAll",
            "$payload": "https://repository.appcell.io/resellerclubcell/schema/domain/domain.payload.json",
            "$result": "https://repository.appcell.io/newresellerclubcell/schema/contact/contact.result.json"
          }
        ],
        "updateList.Contact": [
          {
            "resource": "Contact",
            "action": "updateList",
            "$payload": "https://repository.appcell.io/resellerclubcell/schema/domain/domain.payload.json",
            "$result": "https://repository.appcell.io/newresellerclubcell/schema/contact/contact.result.json"
          }
        ]
      }
    }
  }
}

Properties

resource

Refers to the resources of the software, which are the main API-related objects.

Example:

{ 
   "resource":"Domain"
}

action

Defines the type of action that is applied to the resource according to the schema chosen under “implements”.

Example:

{ 
   "action": "create"
}

payload

Defines the information required for the selected resource. The payload data is provided by the system and also includes an example of how it should be compiled in order for the plugin to properly work when installed. The configuration of the payload is specific for every resource. After the payload data is received and processed an example response is returned.

Note: The payload data may be displayed as key $payload, where a URL that leads to the complete information is the value, or as key payload, where the full data is directly displayed in the JSON file.

Example:

{ 
   "$payload":"https://repository.appcell.io/newresellerclubcell/schema/domain/register.payload.json"
}

result

Displays the result from the payload information and processing.

Note: The result data may be displayed as key $result, where a URL that leads to the complete response information is the value, or as key result, where the full result data is directly displayed in the JSON file.

Example:

{ 
   "$result":"https://repository.appcell.io/newresellerclubcell/schema/domain/domain.result.json"
}

security

By default each plugin has a security key with value protected. That security is handled by the main software (Billia).

There are three types of security:

  1. protected - anyone can access the resource;
  2. public - access is given only to a user who owns the product using the resource (Billia performs a check);
  3. rbac::custom - “rbac” refers to “Role-Based Access Control”; access is given only to a user who has a specific “rbac” permission enabled by Billia.

Example:

{ 
   "security":"public"
}

postpayload

Refers to a change that the main software (Billia) may need to make in its own database, based on the action the postpayload is attached to. The postpayload provides the main software with instructions if an action by it is required and what that action should be. E.g. - the action getEppCode will require the plugin to obtain the epp code but the main software (Billia) would have to also save it in its database as per the instructions of postpayload.

Example:

{ 
   "postpayload":{ 
      "data":{ 
         "auth_info":"{{result}}"
      },
      "type":"overwrite"
   }
}

Resources.json

This file is directly related to Plugin.json file and defines the resources and their actions, that are needed for the configuration of a certain plugin. Resources represent the implementation of technical logic for a business action. It is a developer unit comprised of functionalities and a fundamental concept in any RESTful API.

A Resource has two main functionalities:

  1. REST-based - supports CRUD-based operations and HTTP entity and collection methods. These include actions such as CREATE, UPDATE, DELETE, FETCH/GET, PATCH, etc. May support all or some for a specific resource.

  2. RPC-based - may be applied to any non-rest-related resource action. These include their own schemas and validators, separate from the REST.

Example:

{ 
   "resources":{ 
      "Domain":{ 
         "identifier":"domain",
         "$payload":"https://repository.appcell.io/newresellerclubcell/schema/domain/register.schema.json",
         "$result":"https://repository.appcell.io/newresellerclubcell/schema/domain/domain.schema.json",
         "rest":[ 
            "create",
            "fetch",
            "update"
         ],
         "actions":{ 
            "checkAvailability":{ 
               "$payload":"https://repository.appcell.io/newresellerclubcell/schema/domain/checkAvailability.payload.schema.json",
               "$result":"https://repository.appcell.io/newresellerclubcell/schema/domain/checkAvailability.result.schema.json"
            },
            "getNameServers":[ 

            ],
            "updateNameServers":[ 

            ],
            "getEppCode":{ 
               "identifier":"domain",
               "$payload":"https://repository.appcell.io/newresellerclubcell/schema/domain/domain.payload.schema.json",
               "$result":"https://repository.appcell.io/newresellerclubcell/schema/domain/eppcode.result.schema.json"
            },
            "synchronize":[ 

            ]
         }
      },
      "NS":{ 
         "identifier":"domain",
         "$payload":"https://repository.appcell.io/newresellerclubcell/schema/domain/domain.schema.json",
         "$result":"https://repository.appcell.io/newresellerclubcell/schema/ns/ns.schema.json",
         "rest":[ 
            "fetch",
            "update"
         ]
      },
      "Contact":{ 
         "identifier":"contact_id",
         "$payload":"https://repository.appcell.io/newresellerclubcell/schema/domain/domain.payload.schema.json",
         "$result":"https://repository.appcell.io/newresellerclubcell/schema/contact/contact.result.schema.json",
         "rest":[ 
            "fetchAll",
            "updateList"
         ]
      },
      "Cname":{ 
         "identifier":"ns",
         "$payload":"https://repository.appcell.io/newresellerclubcell/schema/cname/cname.payload.schema.json",
         "$result":"https://repository.appcell.io/newresellerclubcell/schema/cname/cname.result.schema.json",
         "rest":[ 
            "create",
            "fetch",
            "update",
            "delete"
         ]
      },
      "DNS":{ 
         "identifier":"record_id",
         "$payload":"https://repository.appcell.io/dns/schema/record.payload.schema.json",
         "$result":"https://repository.appcell.io/dns/schema/record.result.schema.json",
         "rest":[ 
            "fetchAll",
            "updateList"
         ]
      }
   }
}

Properties

identifier

Defines the identifier for the resource, i.e. the data that will uniquely identify and distinguish this resource from others.

Example:

{ 
   "resources":{ 
      "NS":{ 
         "identifier":"domain"
      }
   }
}

payload

Each resource is equipped with a schema that validates it, located in the payload of that resource. It is used for schema validation by validating the resource payload in the Plugin.json file, for the respective resource, done field by field, where each one must be configured in a specific pattern, example data should be present, a default setup can be set, etc. This validates whether the payload is up to standard depending on the criteria set by the Cell.

Note: The payload data may be displayed as key $payload, where a URL that leads to the complete information is the value, or as key payload, where the full data is directly displayed in the JSON file.

Example:

{ 
   "resources":{ 
      "Domain":{ 
         "$payload":"https://repository.appcell.io/newresellerclubcell/schema/domain/register.schema.json"
      }
   }
}

result

Defines a schema for the response. Through this AppCell can validate the response from the Plugin.

Note: The result data may be displayed as key $result, where a URL that leads to the complete information is the value, or as key result, where the full data is directly displayed in the JSON file.

Example:

{ 
   "resources":{ 
      "Domain":{ 
         "$result":"https://repository.appcell.io/newresellerclubcell/schema/domain/domain.schema.json"
      }
   }
}

rest

Defines the CRUD-based operations and HTTP entity and collection methods used.

These include:

  1. create - creates a new entry with a unique id;
  2. fetch - retrieves data for the specified resource;
  3. update - changes the fields’ data for the resource;
  4. fetchAll - retrieves data for a collection of resources;
  5. updateList - changes the fields’ data for a collection of resources;
  6. patch - partially changes the fields’ data of the resource;
  7. delete - permanently removes the resource and its information.

Example:

{ 
   "resources":{ 
      "Domain":{ 
         "rest":[ 
            "create",
            "fetch",
            "update"
         ]
      }
   }
}

Settings.json

Defines three main factors: settings, options and fields. These refer to the configuration of the plugin.

Example:

{ 
   "settings":{ 
      "userid":"",
      "password":"",
      "Api key":"",
      "TestMode":"0"
   },
  "settings.local": {
	"default": [
	  "server.apihawk.com"
	],
	"servers": {
	  "server.apihawk.com": {
		"hostname": "server.apihawk.com",
		"ip": "127.0.0.1",
		"username": "admin",
		"password": "",
		"nameservers": {
		  "ns1": "ns1.apihawk.com",
		  "ns2": "ns2.apihawk.com"
		}
	  }
	}
  },
  "fields": [
	{
	  "name": "Account Plan",
	  "field_key": "plan",
	  "value": "basic"
	},
	{
	  "name": "Is reseller",
	  "field_key": "reseller",
	  "value": "no"
	}
  ],
   "options":[ 
      { 
         "name":"Domain",
         "key":"domain",
         "type":"text",
         "value_type":"text",
         "required":true,
         "provider":"system",
         "identifier":true
      },
      { 
         "name":"NS1",
         "key":"ns1",
         "type":"text",
         "value_type":"text",
         "required":false,
         "provider":"user"
      },
      { 
         "name":"NS2",
         "key":"ns2",
         "type":"text",
         "value_type":"text",
         "required":false,
         "provider":"user"
      },
      { 
         "name":"NS3",
         "key":"ns3",
         "type":"text",
         "value_type":"text",
         "required":false,
         "provider":"user"
      },
      { 
         "name":"NS4",
         "key":"ns4",
         "type":"text",
         "value_type":"text",
         "required":false,
         "provider":"user"
      },
      { 
         "name":"Email Forwarding",
         "key":"email_forwarding",
         "type":"functional",
         "value_type":"on/off",
         "required":false,
         "provider":"user"
      },
      { 
         "name":"Domain Forwarding",
         "key":"domain_forwarding",
         "type":"functional",
         "value_type":"on/off",
         "required":false,
         "provider":"user"
      },
      { 
         "name":"GDPR Protection",
         "key":"gdpr_protection",
         "type":"functional",
         "value_type":"on/off",
         "required":false,
         "provider":"user"
      },
      { 
         "name":"Theft Protection",
         "key":"theft_protection",
         "type":"functional",
         "value_type":"on/off",
         "required":false,
         "provider":"user"
      },
      { 
         "name":"Privacy Protection",
         "key":"privacy_protection",
         "type":"functional",
         "value_type":"on/off",
         "required":false,
         "provider":"user"
      },
      { 
         "name":"Registrar Lock",
         "key":"registrar_lock",
         "type":"functional",
         "value_type":"on/off",
         "required":false,
         "provider":"user"
      }
   ]
}

Properties

settings

Includes all settings required by the plugin, in order for it to properly work. These include core settings such as access credentials to the vendor, whether it is a test or not, etc. These are simple settings and their creation happens directly in vault_config.

This means that the plugin itself is not required to understand the settings logic or to have its access information hardcoded. That data is provided to it by the main software (Billia) at every request.

Example:

{ 
   "settings":{ 
      "userid":"",
      "password":"",
      "Api key":"",
      "TestMode":"0"
   }
}

fields

Defines specific fields with descriptive purposes, in case they are needed, in order for the specific product to be successfully created. To read more information on Product Fields, please see this article from the Billia Management Panel Manual.

{ 
   "fields":[ 
      { 
         "name":"Account Plan",
         "field_key":"plan",
         "value":"basic"
      },
      { 
         "name":"Is reseller",
         "field_key":"reseller",
         "value":"no"
      }
   ]
}

options

Defines standard Billia Options. This includes the type of options the plugin may require in order to properly work.

Options are product-related settings that require additional information, when a product is purchased. This means specific data that is relevant to the product itself, helps identify it among items of the same type, and gives the purchaser the opportunity to personalize it.

To read more information on Product Fields, please see this article from the Billia Management Panel Manual.

During the install of a plugin the options are directly created in the main software (Billia). If a product from a specific plugin is created, the main software (Billia) automatically attaches all options from the respective module to it.

To read about the difference between Fields and Options, please see this article.

Example:

{ 
   "options":[ 
      { 
         "name":"Domain",
         "key":"domain",
         "type":"text",
         "value_type":"text",
         "required":true,
         "provider":"system",
         "identifier":true
      }
   ]
}

settings.local

A new field feature, titled settings.local, of the Settings.json includes the automatic population of vault_config information (login data) to the etcd storage during the process of installation of the cell. This feature can set the default data, which sets up the whole structure of that cell’s etcd storage.

The functionality of settings.social works only two levels in, i.e. can set up data in maximum two sublevels of the main one.

{
"settings.local": {
    "default": [
      "server.apihawk.com"
    ],
    "servers": {
      "server.apihawk.com": {
        "hostname": "plesk.apihawk.tech",
        "ip": "127.0.0.1",
        "username": "admin",
        "password": "",
        "nameservers": {
          "ns1": "ns1.apihawk.com",
          "ns2": "ns2.apihawk.com"
        }
      }
    }
  }
}

Ui.json

This file represents the frontend and visualization of the cell in the platform. A single plugin can have multiple visualizations in the frontend. These visualizations would be described in the same Ui.json installation file.

Not every cell is equipped with a frontend, so not every cell would require a ui.json installation file. “Ui” stands for “User interface”. The ui.json installation file consists of backend- and frintendmodules.

{
  "backendModules": [
    {
      "url": "https://repository.appcell.io/examplecell/schema/ui/controller.js",
      "urlBase": "example"
    }
  ],
  "frontendModules": [
    {
 "url": "https://repository.appcell.io/examplecell/schema/ui/example-product-dashboard.js",
      "deps": ["example-shared"],
      "slots": ["product-dashboard"],
      "slotFilters": ["example"]
    }
  ]
}

Properties

backendModules

The ui.json file includes a backend for the frontend configuration, used to define various functionalities and to attach needed logic.

url (Controller)

The URL line defines the URL for the Controller. The Controller is an API endpoint that plays the role of the connection between AppCell and the frontend. It can add as many API paths (actions) as needed (e.g. fetch, SSO, etc.). It works in a way where the Controller holds the information on the triggered action and the related customerProductId, as well. That ID is obtained through the URL path of the used service.

The Controller doesn’t include any business logic, it simply calls actions from the Cell and processes their results. It is defined as “api/version/plugin-name/action”.

When an end user triggers a front-end action of an Appcell plugin through the UI, it is then sent through a HTTP request to the Controller. The Controller will associate the action to the specific customerProductId and will send a request to the main software API (e.g. Billia). That software will then send another request over AMQP to AppCell, which will identify the Cell needed and resend the request to it. The Cell then returns a response back through the main software API (Billia) to the Controller with the requested action. Finally, the Controller triggers the action on the side of the frontend and the UI is updated to visualize the result.

Obligatory information for the Controller is the customerProductId and the exact action to be carried out. It runs on a separate server from the Cell. It is important that each possible action included by the Cell, is described both in files Resources.json and Plugin.json.

The URL includes a link leading to the details of the Controller and possible actions. The Controller’s name must match the name of the Controller’s file.

{
   "backendModules":{
      "url": "https://repository.appcell.io/examplecell/schema/ui/controller.js”
   }
}
urlBase

Describes a base endpoint for the plugin.

All plugins have a dedicated directory, titled “plugins”. There, each one can be set with a specific Controller, called by specifying the name of the service, e.g. “spam experts”. It is important that each plugin has a unique address directory, so that when debugging is necessary, it can be done easily with all queries being traceable.

{
   "backendModules":{
     "urlBase": "example"
   }
}

frontModules

The frontend modules include settings and setups for the frontend UI configuration that the end-user operates with.

url

Defines the URL to the JS (Java Script) bundle file.

The JS bundle incorporates multiple JS files with information necessary for the system to correctly and successfully render the plugin. Browsers are usually limited in downloading speed of 8-parallel files. So grouping up those files into a JS bundle assists with the loading times of the browser, end-user UI and the used platform.

{
   "frontendModules":{
      "url":"https://repository.appcell.io/examplecell/schema/ui/example-product-dashboard.js"
   }
}
deps

Defines which JS files should be loaded before the plugin’s code.

If there are any shared dependencies, we can load them first, before the plugin’s code, so that no code duplications occur.

{
   "frontendModules":{
      "deps":[
         "example-shared"
      ]
   }
}
slots

Defines where the UI will be placed in the respective panel, e.g. the “dashboard”.

There could be multiple slots that could support UI visualization and content. Currently, we support “product-dashboard” and “dashboard” visualization slots.

{
   "frontendModules":{
      "slots":[
         "product-dashboard"
      ]
   }
}
slotFilters

Defines for which products the UI will be displayed.

The product specified must coincide with the Module name from the Plugin.json installation file. There are “if” conditions that need to be met, as well. For instance, to activate or deactivate certain actions.

{
   "frontendModules":{
      "slotFilters":[
         "example"
      ]
   }
}