Constants
Application-scoped, dynamically-typed values defined once per deployment — for the endpoints, paths, identifiers, and toggles that should not change as messages flow but should differ between deployments.
A constant in Art2link ESB is a named value defined under an Application, alongside schemas, message types, maps, and variables. It does not belong to any one message; it belongs to the application within this deployment, and any port, pipeline component, map, or routing expression in that application can read it as {{Constant.Name}}.
Constants exist for the values that should travel with an Application as a concept but take on different forms in different deployments — a database host that is dev-sql-01 in one environment and prod-sql-01 in another, an SFTP root path that differs between source and destination, a feature flag that is on in UAT and off in Prod. Where a Variable carries integration state that the runtime mutates as messages move, a Constant carries deployment-specific configuration that the runtime simply reads.
A constant has exactly one value at any moment — the value configured in this deployment. The Constants list inside an Application is three columns wide: Name, Description, Value. There is no Dev column, no Prod column, no resolution-by-environment at runtime. There is only the value in this deployment.
Variation across environments does not happen at runtime — it happens at the seam between deployments. An Application that has been wired to {{Constant.DbHost}} in one deployment is moved to another deployment as a snapshot; the destination supplies its own value for DbHost, and the wiring never changes. See Snapshot import below.
Constants are scoped to an Application. From the application menu, the Constants list shows every constant defined in that application. Each entry has these fields:
| Field | Purpose |
|---|---|
| Name | How the constant is referenced everywhere else — in port adapter settings, pipeline component property values, map bindings, custom function arguments, and routing expressions. Names are flat under the Constant namespace, so they must be unique within the application. |
| Description | Free-text description for human readers. Optional, has no runtime effect. |
| Value | The single value the constant resolves to in this deployment. Editing it changes what every {{Constant.Name}} reference in the application sees, immediately. |
The list view follows the platform's Selected Application behavior — with an Application selected, the list filters to it and the Application column is hidden; with no selection, the list spans every Application you have access to and the column is shown. Creating a new constant uses the same flow: with an Application selected, the form opens with that Application preemptively chosen; without one, the form exposes an Application picker.
A constant does not declare a data type. The value is a string — literally the characters in the Value field — and the consuming context decides how to interpret it. A constant holding 1433 is text until a SQL adapter's Port setting reads it as an integer; a constant holding true is text until a subscription expression compares it to another string.
This matches how Variables behave when read: the same expression engine resolves both, and string-context coercion is identical. The difference is that a Variable's runtime shape can be a scalar, a list, a sub-tree, or a whole message depending on what wrote to it; a Constant's value is only ever the text the user entered.
Constants are not assigned from XPath, not written by pipeline components, and not mutated by the runtime. The only way the value changes is an operator editing the Constants list, or a snapshot import writing a new value into the slot.
Anywhere a string can be typed in the platform — subscription expressions, map bindings, pipeline component property values, custom function arguments, port adapter settings — you can reference a constant with a double-curly-brace token. The exception is naming an object itself: the Name field on a constant, variable, port, message type, schema, etc. is a literal, never an expression.
| Token | Resolves to |
|---|---|
{{Constant.Name}} | The value of the named constant in this application, in this deployment. Always a string, coerced by the consuming context. |
The token grammar is identical to {{Variable.Name}}, {{Promoted.MessageType.Name}}, and {{Message.MessageType}} — the same expression engine evaluates all four. A subscription expression that filters a send port to messages whose currency matches a deployment-specific region code, for example:
{{Message.MessageType}} == "Invoice" && {{Promoted.Invoice.Currency}} == "USD" && {{Constant.RegionCode}} == "EU"
The high-value case is wiring an adapter to constants so the wiring is the same in every deployment and only the values differ. An SFTP send adapter wired this way:
Host: {{Constant.SftpHost}}
Port: {{Constant.SftpPort}}
Username: {{Constant.SftpUser}}
Root path: {{Constant.SftpRootPath}}/{{Variable.CurrentBatchId}}/
moves to the next deployment unchanged. The four {{Constant.…}} tokens resolve against the destination's Constants list; {{Variable.CurrentBatchId}} resolves against runtime state as it always did.
Constants travel through snapshots in two layers. The definitions — names, descriptions, and every reference to {{Constant.Name}} in ports, pipelines, maps, and expressions — are part of the snapshot's open structure. The values are encrypted with a snapshot password.
When the snapshot is imported into a destination deployment, the importer chooses one of two paths:
| Path | What lands |
|---|---|
| Import with the snapshot password | Values are decrypted and shown in the import dialog as a source-value column. The user can carry them across as-is, override any of them, or clear them and fill in later. Whatever is in the destination column at the moment of confirmation is what gets written into the destination deployment's Constants list. |
| Import without the password | Only the definitions come across. Every constant lands in the destination with an empty value. The operator fills them in either from the import dialog (where the source-value column is unavailable) or later from the Constants list. References in ports, pipelines, and maps are intact; they simply resolve to nothing until a value is entered. |
{{Constant.Name}} reference — arrives intact either way.Three patterns account for most of how constants are used in practice. The platform does not enforce any of them — a constant is just a value — but the patterns are worth recognizing because they cover almost every reason to reach for a constant in the first place.
Pattern 1 — Endpoint. Hosts, ports, base URLs, connection strings — values that differ between deployments and never inside one. Wire the adapter setting to {{Constant.Name}} and the wiring is final. Moving the Application across deployments is a snapshot import; the new deployment supplies its own endpoints.
Pattern 2 — Path or identifier. Inbound root folders, outbound drop folders, table name prefixes, tenant IDs, region codes. Strings that show up in more than one place and would otherwise be hard-coded across ports and maps. Centralizing them as a constant means a single row to edit when the value changes, and the change is reflected everywhere the next time the affected stages execute.
Pattern 3 — Feature flag. A boolean-shaped value (held as the string "true" or "false") that gates a subscription expression or a pipeline branch. Toggling the flag is a one-row edit in the Constants list, with no port reconfiguration and no snapshot motion.
{{Message.MessageType}} == "Invoice" && {{Constant.AutoForwardOn}} == "true"
Constants are read-only at runtime. The expression engine resolves each {{Constant.Name}} token at the moment the stage that contains it executes, by looking up the value in the application's Constants list as it currently stands. There is no port assignment stage, no pipeline write, no map write.
| Stage | What happens |
|---|---|
| Definition | A constant is added to the application's Constants list with a Name, Description, and Value. The slot exists; the value is whatever was entered. |
| Edit | An operator changes the Value field in the Constants list. The new value takes effect for any subsequent resolution; no restart, no redeploy. |
| Snapshot import | A new value may be written into the slot when a snapshot is imported into this deployment — with the snapshot password, from the import dialog; or later, from the Constants list. |
| Reference resolution | An expression containing {{Constant.Name}} is evaluated — the current value is substituted as a string, with shape coercion if the consuming context expects something else. |
An empty constant (definition exists, value is blank) resolves to an empty string. Adapter settings that depend on a non-empty value — a host, a port number — will fail at the adapter's validation stage, not at the expression engine. The expression engine itself is permissive: an empty string is a valid resolution.
Constants, Variables, and Promotions are referenced by the same expression engine and share the same token grammar. They describe three different kinds of value, and a single expression can mix all three freely.
| Reference | Whose state it describes | Who writes it |
|---|---|---|
{{Promoted.MessageType.Name}} | This message, at this moment | The runtime, when the message is classified to a message type |
{{Variable.Name}} | The application, at runtime | Port assignment stages and pipeline components only |
{{Constant.Name}} | The application, in this deployment | An operator (via the Constants list or the snapshot import dialog) |
The three are intentionally separate. A value that describes this message belongs on a promotion. A value that the integration mutates as it goes belongs in a variable. A value that differs only between deployments and never within one belongs in a constant. Mixing them in a single expression is fine and common:
{{Message.MessageType}} == "Invoice"
&& {{Promoted.Invoice.Currency}} == "USD"
&& {{Variable.InvoiceForwardingEnabled}} == "true"
&& {{Constant.RegionCode}} == "EU"
That is the whole job
Define a constant under the application, give it a value for this deployment, reference it as {{Constant.Name}} wherever you need it. Untyped, application-scoped, one value at a time. Snapshots carry the wiring; the password decides whether they carry the values.