Appmixer Architecture
Last updated
Last updated
The main system that manages flows, accounts, users, orchestrates components within running flows and provides a HTTP REST API interface to access all the entities within Appmixer. The Appmixer engine is implemented in NodeJS and can run on a single node or in cluster. The engine is horizontally scalable providing high availability and fault tolerance capabilities.
JavaScript HTML 5 SDK that allows to seamlessly embed any of the Appmixer UI widgets (including the drag&drop workflow designer) to any 3rd party web page. The SDK communicates with the engine via REST API. Appmixer JavaScript SDK offers heavy customization capabilities, including changing of the look&feel (via themes), localization of all the text in the UI and even implementing custom component configuration Inspector fields.
A standalone admin panel providing overview of all the flows and users in Appmixer together with system and modules configuration, ACL lists, system webhooks and more.
Command line tool for development, testing and management of custom components. It can also be used to manage, export and import flows.
Appmixer Engine uses RabbitMQ as a message broker for all data messages passing through the running flows. Also, RabbitMQ serves as an intermediary for logs before entering ElasticSearch.
Storage for all static data such as:
Flows
Users
System Configuration
Accounts
Component States
Dead-letter collection
Component Behaviour (code)
Modifiers (code)
Files (GridFS)
Data Stores
Telemetry
Key-value store that holds the state of the cluster, provides caching and synchronization (distributed locks).
Search & analytics engine that stores all the activity of all the running flows, system logs & errors. Logs can be retrieved by using the Appmixer REST API (Insights). Alternatively, standard tools such as Kibana can be used for in-depth analysis, technical support and maintenance.
Clients (Appmixer Studio, Appmixer JavaScript SDK) provide a drag&drop No-code designer for workflow automations. In design phase, the user is adding components to a flow, configures components, assigns accounts and interconnects components to form a data flow pipeline, possibly with logic and loops.When configuring components, the user can use variables to reference data that will be available at the flow runtime. These variables are outputs of components back in the chain (collection of all the outputs of all the ancestors of the configuring component).Variables can be modified at the flow runtime by applying modifiers. These modifiers are configurable and are represented as parametrized JavaScript functions that manipulate a single input. Modifiers can be chained to produce more complex expressions.The result of the design phase is a new or updated flow descriptor (JSON representation of the flow graph) and metadata, together with account assignment (externally linked) and modifiers (externally linked). Note that the flow descriptor in itself is not complete, the engine assumes the linked components and modifiers exist in the system. Therefore, copying a flow descriptor to another tenant can only work if the linked components and modifiers also exist in the target tenant.
Flow is in the running phase when its configuration has been completed and the flow has been started. From this point, the flow does not require any user interaction and is executed and maintained by the engine in the background.During the flow running phase, the engine is responsible for passing external inputs to the associated trigger components (e.g. webhooks), scheduling polling type of triggers, orchestrating message passing between connected components, handling errors, retries, making sure defined quota limits are honored and logging all activity.The engine reports all unexpected events via system defined webhooks. This allows the customer to define custom actions in case e.g. the flow can’t run since a component in it lost authentication tokens (e.g. a 3rd party connected account was externally revoked).The engine has a built-in support for the most common authentication mechanisms (OAuth 1, OAuth 2, API keys, Basic auth, …) and can be extended with new ones. It automatically handles token refreshing for relevant authentication types.Components within a flow (and in general, when defined) don’t know about each other. They are black boxes that can be arbitrarily interconnected to produce different automations.If a message cannot be processed (e.g. a component tried to call an API which keeps failing multiple times - configurable) the engine stores such a message in a dead-letter collection in MongoDB and notifies a system configured webhook. This allows the customer to further inspect such messages, retry their processing and/or notify the end-user of such errors.The engine provides built-in scheduling mechanism, offering component developers an intuitive way for defining different types of timers, schedulers and throttles.