Skip to content
Art2link ESB v2.02 LTS HomeDocumentationBlogContact
Core concepts/Constants

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.

APPLICATION — ORDERS INTEGRATION this deployment only CONSTANT DbHost Order database host prod-sql-01 one value, here, now CONSTANT SftpRootPath Inbound SFTP root /drop/orders one value, here, now CONSTANT RegionCode Routing region EU one value, here, now

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.

One deployment, one environment. A single installed instance of the platform is the environment. The platform does not hold multiple sets of values for the same constant simultaneously. If you need Dev, UAT, and Prod values to coexist, you need three deployments.

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:

FieldPurpose
NameHow 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.
DescriptionFree-text description for human readers. Optional, has no runtime effect.
ValueThe 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.

No data type field. Constants are deliberately untyped at declaration time — the value is whatever the user typed or pasted into the Value field, treated as a string by the expression engine and coerced by whatever consumes it. See Dynamic typing below.

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.

TokenResolves 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:

EXPRESSIONsubscription on a send port
{{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:

ADAPTER SETTINGSSFTP send adapter
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.

SOURCE DEPLOYMENT DbHost = dev-sql-01 SftpRootPath = /incoming RegionCode = EU Take snapshot password required .snap FILE exported SNAPSHOT — TWO LAYERS LAYER 1 — CLEAR Names, descriptions, references in ports, maps, pipelines structure of the app LAYER 2 — ENCRYPTED All constant values unreadable without password IMPORT — WITH PASSWORD Values decrypted and shown in import dialog Carry as-is, override, or clear and fill later developer + operator workflow IMPORT — NO PASSWORD Values do not import Definitions land, value slots empty Operator fills them in secrets stay in source env DESTINATION DEPLOYMENT DbHost = prod-sql-01 SftpRootPath = /drop RegionCode = NA Same wiring, deployment-specific values {{Constant.…}} references unchanged

When the snapshot is imported into a destination deployment, the importer chooses one of two paths:

PathWhat lands
Import with the snapshot passwordValues 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 passwordOnly 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.
This is the carry-or-not mechanism. A developer can hand a snapshot to an operator without sharing the source deployment's password. The operator imports the application's structure into a higher environment and fills in the values from a vault that the developer never sees. The wiring — every {{Constant.Name}} reference — arrives intact either way.
Editing at import is optional. The import dialog always lets the operator commit immediately with whatever the dialog shows (filled or empty), and editing later from the Constants list is always possible. Choosing "edit later" is not the same as choosing "no password" — password decides whether source values are readable; the dialog decides whether the operator changes them now.

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 {{Constant.SftpHost}} {{Constant.SftpPort}} {{Constant.SftpUser}} wired into the adapter SFTP, SQL, API, MQ — anything with a host never the same across deployments PATTERN 2 Path or identifier {{Constant.SftpRootPath}} {{Constant.RegionCode}} single string of truth Folders, table prefixes, region codes, tenant IDs readable, editable, one place PATTERN 3 Feature flag {{Constant.AutoForwardOn}} "true" | "false" gates a subscription expression On in UAT, off in Prod — one row to flip no port reconfiguration

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.

EXPRESSIONsubscription on a send port
{{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.

StageWhat happens
DefinitionA constant is added to the application's Constants list with a Name, Description, and Value. The slot exists; the value is whatever was entered.
EditAn operator changes the Value field in the Constants list. The new value takes effect for any subsequent resolution; no restart, no redeploy.
Snapshot importA 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 resolutionAn 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.

ReferenceWhose state it describesWho writes it
{{Promoted.MessageType.Name}}This message, at this momentThe runtime, when the message is classified to a message type
{{Variable.Name}}The application, at runtimePort assignment stages and pipeline components only
{{Constant.Name}}The application, in this deploymentAn 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:

EXPRESSIONsubscription combining all three
{{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.