Recommended Primitive Types
Primitive Types: Concept
The FNZ Studio Platform uses two kinds of Business Objects related to data definition:
- Primitive Types
- Data Classes
A Primitive Type denotes a single value, that is, a value that is atomic with respect to the FNZ Studio scripting language. From a model point of view, a Primitive Type is a Business Object which is maintained in the Business Object Repository.
However, many of such Primitive Types are closely related to a specific feature of FNZ Studio. Values of those Primitive Types are actually references to special objects managed by FNZ Studio. For example, HttpRequest represents an HTTP request sent to FNZ Studio, while WorkflowInstance represents a Process Instance. Primitive Types of this kind allow a Solution to use the Script Language to interact with FNZ Studio and get access to some of its core features and services.
It is important to understand that Primitive Types like the ones mentioned in the preceding paragraph are very different than the simple, generic, and immutable Primitive Types like String, Double, or Boolean: They often have a complex inner structure, very special runtime behavior, and sometimes even installation-specific aspects. Their close relationship to the runtime aspects of FNZ Studio makes it difficult to work with them. Using them in the wrong way can harm the stability, performance, or security of your Solution or the FNZ Studio Platform as a whole, which is why many of them are classified as Unrecommended Primitive Types.
Recommended Primitive Types: Concept
Recommended Primitive Types are Primitive Types that are generally safe to use in a Value Store. They have the following characteristics:
- Immutable – They have a fixed structure that does not change between releases, therefore they are not subject to potentially risky modifications in the future.
- Simple – They have a simple structure and it is easy to detect if they have changed. For example, let's suppose you have a String Data Value, and this value changes. In this case, FNZ Studio detects that the value has changed and that it has to be updated in the Value Store. On the contrary, complex Primitive Types in the Value Store might cause issues in understanding if a Data Value has changed. For example, if you have a User Data Value Primitive Type and you change the first name, FNZ Studio might fail to detect that the Data Value needs to be updated in the Value Store.
- Serializable – They can always be materialized.
- Generated from the core Platform – They are always generated by the core Platform. In contrast, some other Primitive Types are generated by extensions. Since it cannot be guaranteed that the extension is up and running before the Value Store, Primitive Types generated by extensions can cause serialization and deserialization issues if not carefully managed in the extension.
- Compatible with Business Data Storage (BDS)
Unrecommended Primitive Types: Concept
Unrecommended Primitive Types are Primitive Types that do not meet the requirements described in the previous section. These Primitive Types can cause problems during serialization and deserialization, make it hard to detect whether a variable or property value has changed, and lead to unexpected behavior because of the copy-by-value semantic of a reference type, e.g. automatic cloning/decoupling of value objects when Value Stores are serialized and deserialized.
The Primitive Types evaluated by FNZ Studio can be of three types (see all details in the sections below):
- 'Black List' Primitive Types – These are likely to cause issues in the Value Store and must be avoided. A validation warning is issued in FNZ Studio.
- 'Gray List' Primitive Types – These are less likely to cause issues in the Value Store, but should be avoided when possible. NO validation warning is issued in FNZ Studio.
- 'White List' Primitive Types – These Primitive Types are safe to use. NO validation warning is issued in FNZ Studio.
Validation of Primitive Types in FNZ Studio
As mentioned above, our Platform includes a validation mechanism that identifies Primitive Types that are likely to cause issues in the Value Store. Two cases need to be considered:
1. You are using Unrecommended Primitive Types in your existing Solution
If you have upgraded your existing Solution to Appway 9.1 or higher from an older version, it is possible that you are using some Unrecommended Primitive Types that were not identified in previous versions.
In this case, your Solution continues to work as expected, but a validation warning is issued notifying you that you should replace those Primitive Types.
Validating an Unrecommended Primitive Type (e.g. HttpRequest) in existing Solutions issues a Warning message.
2. You add Unrecommended Primitive Types when developing new Solutions
Once you start developing your new or upgraded Solution, Unrecommended Primitive Types can no longer be selected in the Business Object selectors available for:
- Properties of Data Classes
- Variables of Process, Screen, PDF Output, and Data Logic Business Objects
Therefore, the system itself prevents you from using Unrecommended Primitive Types.
Adding an Unrecommended Primitive Type (e.g. HttpRequest) is prevented by FNZ Studio.
Adding a Primitive Type to the List of Recommended Primitive Types
In some cases, you might need to use an Unrecommended Primitive Type in your Solution as you do not have a viable alternative. In such edge cases, you can edit the related configuration property to whitelist the Primitive Type so that it can be used. Do the following:
- Go to System Configuration > Configuration Properties.
- Edit the
nm.primitiveTypes.recommended.whitelistproperty to include the needed Primitive Types in a comma-separated string. - The specified Primitive Types are now available in the Business Object selectors and can be used. Note that FNZ Studio still considers whitelisted Primitive Types as unrecommended, and therefore issues an Info validation message whenever one is used.
Note: Remember that only Business Object selectors available for properties of Data Classes, and variables of Process, Screen, PDF Output, and Data Logic Business Objects are affected.
An Unrecommended Primitive Type can be added to the Configuration Properties if strictly necessary.
Validating an Unrecommended Primitive Type added to the Configuration Properties (e.g. WorkflowToken) issues an Info message.
Reference: Recommended and Unrecommended Primitive Types
- The list of Recommended Primitive Types is continuously evaluated, and Primitive Types can be reclassified as Unrecommended in future Platform versions.
- A complete list of Unrecommended Primitive Types is not available here, as some of them can be created by custom extensions.
The following tables summarizes how Primitive Types are handled in FNZ Studio:
| Category | Platform Config Status | Platform Behavior | Platform Validation |
|---|---|---|---|
| Recommended | (not relevant) | Can be chosen in Business Object Selectors | No validation warning |
| Unrecommended, Medium-severity | (not relevant) | Can be chosen in Business Object Selectors | No validation warning |
| Unrecommended, High-severity | NOT whitelisted in configurationnn Whitelisted in configuration | CANNOT be chosen in Business Object Selectorsnn Can be chosen in Business Object Selectors | WARNING validationnn INFO validation |
Migrating from Unrecommended Primitive Types
As described in detail at the beginning of this article, Unrecommended Primitive Types have several characteristics that make it difficult to work with them. Using Unrecommended Primitive Types in the wrong way can harm the stability, performance, or security of your Solution or FNZ Studio as a whole.
The following sections show how you can build or modify your Solution to use Unrecommended Primitive Types in a safe manner.
Best Practice when Dealing with Unrecommended Primitive Types
To avoid issues related to the usage of Unrecommended Primitive Types, it is a best practice to minimize their usage: A good approach is to limit the use of an instance of an Unrecommended Primitive Type to a single Script Task or a single Script Function. This script can load or create an instance of an Unrecommended Primitive Type, make changes to it, and store it. But the instance only lives in the local scope of this script. All information passed into the script or somehow returned by the script must only use Recommended Primitive Types or Data Classes.
Note: The following examples discuss Primitive Types currently not classed as "unrecommended", as these are most suitable for explaining the best practice based on a simple use case. However, the methodology explained in the examples can be applied to any of the Unrecommended Primitive Types.
Example 1: A Process to Create a New Platform User
A Process is built to create a new Platform user. The Process contains multiple Screens to collect information about the new user like their first name, last name, and email address. Platform users are represented by instances of the Primitive Type User.
Note: The Primitive Type User is such a common type that FNZ Studio contains some special code to guarantee correct serialization when a User object is stored in a Value Store. Therefore, the Primitive Type User is considered safe and categorized as a Recommended Primitive Type. However, consider that:
- User has a complex inner structure and is not immutable.
- There is a risk of lost updates on concurrent modifications.
- A User object stops to be a managed object when it is stored to and then reloaded from a Value Store.
Bad implementation
- The developer adds a variable
$userof the type User to the Process. An instance of this type is created withNewObject(User)and stored in the variable$userat the beginning of the Process. - All information entered during the execution of the Process is immediately stored in the properties of this User object.
- At the end of the Process, the User object is passed to the User Service to be saved in FNZ Studio's user database.
This implementation does not follow the above best practice because the User object is created when the Process is started and then used throughout the complete execution of the Process. This means that the User object must be persisted in the Value Store in the meantime. However, this can be avoided following the implementation below.
Good implementation
- The developer only adds variables of Recommended Primitive Types and Data Classes to the Process.
- The developer creates a helper Data Class "UserData" with properties to store all information collected during the Process.
- At the end of the Process, there is a single Script Task to create the actual Platform user. This script creates an instance of the type User, copies all information from the UserData object into the User object, and then passes the User object to the User Service to have it saved.
- When the script execution ends, the User object is no longer needed.
The important difference is that the instance of the type User is only created at the very last moment in the Process, and only lives in the local scope of the Script Task used to create a new Platform user. There is no User object present in the Process before, and there is no User object present in the Process afterwards.
Example 2: Handling Exceptions
Bad implementation
A Process uses a try/catch block in a Script Task to handle exceptions. If an exception occurs, it is automatically stored in a local implicit variable $exception of the type Exception.
Good implementation If the Process needs to be able to react to the exception later on, it should not store the Exception object in a variable of the Process. Instead, it should extract all relevant information from the Exception object and store it in variables using Recommended Primitive Types.
Best Practice Summary
In both "good implementations" explained in the examples above, the use of Unrecommended Primitive Types is limited to the point in time when the Solution is "interacting" with Platform components or services. During normal Process execution, the Solution should only use custom/Solution-specific data structures built with Recommended Primitive Types and Data Classes. Instances of Unrecommended Primitive Types can be used to exchange data with FNZ Studio only when calling a service like the User Service or when integrating with other Platform features. At that time, custom data structures are mapped to or from instances of Unrecommended Primitive Types.