The following provides examples on how Camunda Spin can be used in the process engine to work with JSON data. For illustration purposes, let us assume that a String process variable customer containing JSON exists. It has the following content:

If you want to learn how to use JSON objects in an embedded form, please take a look at the .

Further documentation about the usage of Spin can be found in the Camunda Spin Dataformat Reference.

Expression Language Integration

The Spin entry functions can be used wherever the process engine allows expression language. The following BPMN snippet shows a conditional sequence flow expression based on the customer’s post code:

  1. ...
  2. <sequenceFlow>
  3. <conditionExpression xsi:type="tFormalExpression">
  4. ${S(customer).prop("address").prop("post code").numberValue() == 1234}
  5. </conditionExpression>
  6. </sequenceFlow>
  7. ...

If your variable is already a , and not a string like in the previous example, you can omit the S(…) call and directly access the variable:

  1. ...
  2. <sequenceFlow>
  3. <conditionExpression xsi:type="tFormalExpression">
  4. ${customer.jsonPath("$.adress.post code").numberValue() == 1234}
  5. </conditionExpression>
  6. ...

Scripting Integration

Native JSON Variable Value

The native variable value for JSON makes it possible to easily parse a JSON string and wrap it inside an object without the need to have a class representing the JSON. Suppose we want to save the JSON inside a process variable for later use, we could do the following inside a JavaDelegate:

  1. public class MyDelegate implements JavaDelegate {
  2. @Override
  3. public void execute(DelegateExecution execution) throws Exception {
  4. + "\"address\" : {"
  5. + "\"street\" : \"12 High Street\","
  6. + "\"post code\" : 1234"
  7. + "}"
  8. + "}";
  9. JsonValue jsonValue = SpinValues.jsonValue(json).create();
  10. execution.setVariable("customerJonny", jsonValue);
  11. }
  12. }

The call to SpinValues.jsonValue(…).create() will transform the string into a Jackson object wrapped by Spin.

If we wanted to retrieve the JSON in another JavaDelegate and, e.g., add some more information, we could do this easily:

  1. public class AddDataDelegate implements JavaDelegate {
  2. public void execute(DelegateExecution execution) throws Exception {
  3. JsonValue customer = execution.getVariableTyped("customerJonny");
  4. customer.getValue().prop("creditLimit", 1000.00);
  5. //{"name":"jonny","address":{"street":"12 High Street","post code":1234},"creditLimit":1000.0}
  6. }
  7. }

When retrieving the JSON value via execution.getVariableTyped() there are two options: serialized and deserialized.Retrieving the variable deserialized by calling either getVariableTyped("name") or , the JsonValue contains the wrapped Jackson object to represent the JSON data. Calling getVariableTyped("name", false) results in JsonValue containing only the raw string, which is advantageous if you only need the string, e.g., to pass it to another API.

Serializing Process Variables

A Java object can be serialized using Spin’s built-in JSON data format. Let us assume that there are two java classes, com.example.Customer and com.example.Address, with the following structure:

  1. Address address = new Address("12 High Street", 1234);
  2. Customer customer = new Customer("jonny", address);
  3. ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("aProcess");
  4. ObjectValue typedCustomerValue =
  5. Variables.objectValue(customer).serializationDataFormat("application/json").create();
  6. runtimeService.setVariable(processInstance.getId(), "customer", typedCustomerValue);

The decisive statement is

  1. ObjectValue typedCustomerValue =

This creates a variable value from the Customer object. The invocation serializationDataFormat("application/json") tells the process engine in which format the variable should be serialized. This name must match the name of a data format known to Spin. For example, application/json is the name of the built-in JSON data format.

Once the variable is set, its serialized value can be retrieved using the type variable API. For example:

The engine can be configured to persist all objects for which no explicit data format is specified as JSON. The process engine configuration offers a property defaultSerializationFormat. To configure default JSON serialization, set this property to . Now, the invocation runtimeService.setVariable(processInstance.getId(), "customer", new Customer()) directly serializes the customer object as JSON without explicit declaration of the format.