Skip to main content
Version: 1.3

Maps

LittleHorse provides a native MAP variable type that stores strongly-typed key/value pairs.

Use MAP when you want compile-time and runtime guarantees that every key and value in your map conforms to a specific type. This is in contrast to JSON_OBJ, which is schema-less and performs no type validation on its contents.

info

Map support was added in LittleHorse 1.2. Only the Java SDK supports declareMap() as of this release. Support for other SDKs is planned for future releases.

Contrast with JSON_OBJ​

FeatureMAPJSON_OBJ
Key type enforcementYes — must be a primitive typeNo
Value type enforcementYes — enforced at ingressNo
Use caseStrongly-typed key/value dataArbitrary JSON objects

Supported Key and Value Types​

Keys must resolve to a primitive type (e.g., STR, INT, DOUBLE, BOOL). The server enforces this constraint at ingress.

Values can be any TypeDefinition:

  • Primitives: INT, DOUBLE, STR, BOOL, BYTES, etc.
  • Structs: backed by a registered StructDef or an embedded InlineStructDef
  • Typed collections: ARRAY
note

MAP variables cannot contain JSON_OBJ or JSON_ARR values. Those types do not have a defined schema for validation and would defeat the purpose of using a strongly-typed map.

In Practice​

To use a MAP variable in LittleHorse:

  1. Declare a MAP variable in your WfSpec using declareMap().
  2. Produce and consume maps in your task workers.
  3. Use mutation operations to manipulate map contents.

Declaring a MAP Variable​

Use the declareMap method on WorkflowThread to create a typed map variable. You specify both the key type and value type as Java classes.

Signature:

WfRunVariable declareMap(String name, Class<?> keyType, Class<?> valueType)

Both type parameters must be Java types that the LittleHorse type system can resolve to a supported TypeDefinition.

import io.littlehorse.sdk.wfsdk.WfRunVariable;
import io.littlehorse.sdk.wfsdk.WorkflowThread;

public void wfLogic(WorkflowThread wf) {
// String keys, Long values
WfRunVariable myMap = wf.declareMap("my-map", String.class, Long.class);

// String keys, array-of-Long values
WfRunVariable myMapOfArrays = wf.declareMap("map-of-arrays", String.class, Long[].class);
}

Inline Map Construction​

Java's LHMapBuilder creates a native map value while the workflow is being authored. Each put() accepts literal values, workflow variables, expressions, or task outputs, so keys and values can be resolved at runtime.

Java only

LHMapBuilder and WorkflowThread.buildMap() are currently available only in the Java SDK. Pending support for other SDKs in a future release.

import io.littlehorse.sdk.wfsdk.LHMapBuilder;

public void wfLogic(WorkflowThread wf) {
WfRunVariable inventory = wf.declareMap("inventory", String.class, Long.class);
WfRunVariable item = wf.declareStr("item");
WfRunVariable quantity = wf.declareInt("quantity");

LHMapBuilder initialInventory = wf.buildMap()
.put("apples", 10L)
.put(item, quantity);

inventory.assign(initialInventory);
wf.execute("save-inventory", initialInventory);
}

Mutation Operations​

The MAP type supports the following mutation operations:

OperationDescription
ASSIGNReplace the entire map with a new value
EXTENDMerge two maps; existing keys in LHS are overwritten by RHS values
REMOVE_KEYRemove an entry by key (RHS must be compatible with the key type)
put()Set or replace one entry by key (Java only)

Adding or Replacing an Entry​

Use put() to assign one map entry. The key can be a literal or any expression that resolves to the map's key type; writing an existing key replaces its value.

Java only

WfRunVariable.put() is currently available only in the Java SDK. Pending support for other SDKs in a future release.

import io.littlehorse.sdk.wfsdk.NodeOutput;
import io.littlehorse.sdk.wfsdk.WfRunVariable;
import io.littlehorse.sdk.wfsdk.WorkflowThread;

public void wfLogic(WorkflowThread wf) {
WfRunVariable myMap = wf.declareMap("my-map", String.class, Long.class);
WfRunVariable key = wf.declareStr("key");

// Assign the result of a task to the map
NodeOutput produced = wf.execute("produce-map");
myMap.assign(produced);

// Set an entry using a runtime-resolved key
myMap.put(key, 42L);
}

Further Resources​