Skip to main content

Configuration Examples

To clarify the descriptions above, let us look at some examples:

Getting a Simple JSON Value

In this example, we are using a REST service that fetches information that we want to store in a process or case instance.

Suppose we have a REST service that fetches client information using the URL /clients/${id}. The service returns client information as follows:

{
"id": 123,
"firstName": "John",
"lastName": "Doe",
"address": "Somelane 3, 1234 City",
"birthDate": "1970-01-01T01:02:03.456Z",
"creditScore": 123
}

The service definition looks as follows:

07 example 01 01

And its one operation:

07 example 01 01b

07 example 01 01b

07 example 01 01b

07 example 01 01b

Note how the input parameter clientId is used as part of the URL for this operation.

Also, note that we are only returning a handful of the available properties. Not having the other properties (e.g., creditScore) in the output parameter list filters those out.

We can now create a simple process that uses that service:

08 example 01 02

Assuming the process model has a start form with clientId, the parameter mapping looks as follows:

09 example 01 03

Here we are mapping the value of the clientId from the start form to the single input parameter and the first name, last name, and birthDate are mapped to specific output variables. If this process was part of a case, we could push the variables upwards using ${root.clientFirstName} or ${parent.clientFirstName}. The response code is stored in the variable responseCode. The error output parameter responseBody is mapped to the variable responseBodyOnError.

If we run this process say in Flowable Work, the user task after starting the process instance now shows something like this, which validates that the service was invoked and variables were passed back and forth correctly.

10 example 01 04

Using Paths to get a Nested Value

Let us adapt the example in the previous section to include nested fields in the response. For example, the firstName and lastName are under the info field and the birthDate is further nested under the dateInfo property:

{
"id": 123,
"info": {
"firstName": "John",
"lastName": "Doe",
"address": "Somelane 3, 1234 City",
"dateInfo": {
"birthDate": "1970-01-01T01:02:03.456Z"
},
"creditScore": 123
}
}

To make the example in the previous section work, the output path is set to info (as everything is nested under that property), and the path of the birthDate is set to dateInfo (the path is relative to the output path of the operation):

11 example 02 01a

And for the birthDate parameter:

11 example 02 01b

note

The Path is used to navigate to the object and the Name is used to denote the attribute in the json response body.

Creating error output parameter

To create an error output parameter, the Map on error flag must be set to true. 11 example 02 01b

Getting a List/Array of Values

In this example, we have a REST endpoint that returns an array of clients:

    [
{
"id": 123,
"info": {
"name": "John",
"lastName": "Doe",
"address": "Somelane 3, 1234 City",
"dateInfo": {
"birthDate": "1960-01-01T01:02:03.456Z"
},
"creditScore": 123,
"employer": {
"name": "Flowable",
"address": "Somelane 3, 4432 Bern"
}
}
},
{
"id": 456,
"info": {
"name": "Jane",
"lastName": "Doe",
"address": "Somelane 3, 1234 City",
"dateInfo": {
"birthDate": "1963-01-04T01:02:03.456Z"
},
"creditScore": 5,
"employer": {
"name": "Acme",
"address": "Somelane 177, 10365 Berlin"
}
}
},
{
"id": 789,
"info": {
"name": "Jimmy",
"lastName": "Doe",
"address": "Somelane 3, 1234 City",
"dateInfo": {
"birthDate": "1990-01-01T01:02:03.456Z"
},
"creditScore": 123,
"employer": {
"name": "Megacorp",
"address": "Somelane 256, 60604 Chicago"
}
}
}
]

Again reusing the service definition from the previous example, we now add a new operation.

We map the required data from the returned array objects into service output parameters. In this example we are only interested in the id, name and lastName of the person:

The operation configurations looks like follows:

12 example 03 01

12 example 03 01

12 example 03 01

The individual output parameter configuration are listed in the tables below. Only required or non-default values are listed.

Client ID

ParameterValue
LabelPerson ID
Nameid
SourceDefault
TypeLong

First Name

ParameterValue
LabelFirst Name
Namename
SourceDefault
TypeString
Path/info

Last Name

ParameterValue
LabelLast Name
NamelastName
SourceDefault
TypeString
Path/info

Note that this example uses Path and Name to point to the name and lastName attributes. The Path is used to navigate to the object and the Name is used to denote the attribute in the JSON response body.

note

It is important to understand that in the case of arrays, the configuration of the output parameters is applied to each element of the array.

The result looks like this:

[
{
"name": "John",
"lastName": "Doe",
"employerName": "Flowable",
"id": 123
},
{
"name": "Jane",
"lastName": "Doe",
"id": 456
},
{
"name": "Jimmy",
"lastName": "Doe",
"id": 789
}
]

This service can now be used in a process or case model:

13 example 03 02

Note that only the Output variable is set. For array return types, the Service Output Parameters mapping can be ignored.

Internally, an ArrayNode is returned. This can be used to configure multi-instance activities, such as user tasks. The configuration of a multi-instance activity could look like this:

13 example 03 02

Using Mapping name to resolve name overlaps

Based on the JSON structure from the previous example, we now want to extend the service to additionally return the employer name and employer address line together with the client address line.

The problem is, the attribute names name and address overlap for the client info and the employer in this example. This can be fixed using the Mapping name configuration field.

The service output parameter configuration looks like this:

Client Address

ParameterValue
LabelClient Address
Nameaddress
SourceDefault
TypeString
Path/info

Employer Name

ParameterValue
LabelEmployer Name
Namename
SourceDefault
TypeString
Path/info/employer
Mapping nameemployerName

Employer Address

ParameterValue
LabelEmployer Address
Nameaddress
SourceDefault
TypeString
Path/info/employer
Mapping nameemployerAddress
note

Note the usage of Mapping name, Path and Name in the output parameter configurations.

The target attribute in the service response JSON body is expressed by the Path to navigate to the object and the Name to denote the attribute. Mapping name is then used to resolve the overlapping names.

The result looks like this:

[
{
"name": "John",
"lastName": "Doe",
"address": "Somelane 3, 1234 City",
"employerAddress": "Somelane 3, 4432 Bern",
"employerName": "Flowable",
"id": 123
},
{
"name": "Jane",
"lastName": "Doe",
"address": "Somelane 3, 1234 City",
"employerAddress": "Somelane 177, 10365 Berlin",
"employerName": "Acme",
"id": 456
},
{
"name": "Jimmy",
"lastName": "Doe",
"address": "Somelane 3, 1234 City",
"employerAddress": "Somelane 256, 60604 Chicago",
"employerName": "Megacorp",
"id": 789
}
]

'Source': Returning the response payload and response headers

The Source configuration of the service output parameter configuration allows you to configure to return the response payload, response headers, etc. The different options are showcased in this section.

It is possible to return the response payload as-is as a service output parameter. To do this, the Source setting can be set to Response body. The entire response body will be assigned to the output parameter.

Given this JSON payload:

{
"id": 117,
"info": {
"name": "Jimmy",
"lastName": "Doe",
"address": "Somelane 3, 1234 City",
"dateInfo": {
"birthDate": "1990-01-01T01:02:03.456Z"
},
"creditScore": 123
}

The following output parameter configurations showcase all possible values for Source, when applied to the response above.

Source: Status Code

ParameterValue
LabelResponse Status Code
NameresponseStatusCode
SourceStatus Code
TypeLong

Source: Full response body

ParameterValue
LabelFull response body
NameresponsePayload
SourceFull response body
TypeJSON

Source: All response headers

ParameterValue
LabelAll response headers
NameresponseHeaders
SourceAll response headers
TypeArray

Source: Specific response header

ParameterValue
LabelSpecific response header
NameresponseHeaderSpecific
SourceSpecific response header
TypeString

Given the configuration above, the result looks like this:

{
"responseStatusCode": 200,
"responseHeaders": [
{
"key": "Content-Type",
"value": "application/json; charset=utf-8"
},
{
"key": "Content-Length",
"value": "309"
}
],
"responsePayload": {
"id": 117,
"info": {
"name": "Jimmy",
"lastName": "Doe",
"address": "Somelane 3, 1234 City",
"dateInfo": {
"birthDate": "1990-01-01T01:02:03.456Z"
},
"creditScore": 123
}
},
"responseHeaderSpecific": "application/json; charset=utf-8"
}
caution

Caution with the Full response body and All response headers setting

In general, it is strongly recommended to define the output parameters to return only the data that is needed in the case or process model. In this way, the amount of data potentially stored as variables is kept to the required minimum.

List/Array Behavior

The behavior for arrays is a bit different in terms to the Source. As the output parameter configuration is applied to every element in the array, the service output in the used configuration above would result in the following service response when using this array response:

REST array response body

[
{
"id": 17,
"info": {
"name": "Jimmy",
"lastName": "Doe",
"creditScore": 5
}
},
{
"id": 456,
"info": {
"name": "Jane",
"lastName": "Doe",
"creditScore": 5
}
}
]

Service response after applying the output parameter mappings above

[
{
"responseStatusCode": 200,
"responseHeaders": [
{
"key": "Content-Type",
"value": "application/json; charset=utf-8"
}
],
"responsePayload":
{
"id": 17,
"info": {
"name": "Jimmy",
"lastName": "Doe",
"creditScore": 5
}
},
"responseHeaderSpecific": "application/json; charset=utf-8"
},
{
"responseStatusCode": 200,
"responseHeaders": [
{
"key": "Content-Type",
"value": "application/json; charset=utf-8"
}
],
"responsePayload":
{
"id": 456,
"info": {
"name": "Jane",
"lastName": "Doe",
"creditScore": 5,
}
},
"responseHeaderSpecific": "application/json; charset=utf-8"
}
]

Because the output parameter mappings are applied to each element individually, the resulting array contains objects with the configured service output parameters. This means that, for example, responseHeaders are repeated for each array element.

Posting to a REST Service

Suppose there exists another REST endpoint that allows creating a client object. Adding such an operation is similar to the steps above. First, add a new 'create' operation to the example from above and now:

  • Configure a set of input parameters that populate the JSON body when doing the POST.

  • For more complex use cases, a custom Freemarker template can be used (see the Service Registry Engine Developer Guide.

If the REST endpoint accepts a simple flat JSON structure for creating a client, the operation configuration could, for example, look like:

14 example 04 01

14 example 04 01

14 example 04 01

Authorization for a REST Service

Depending on how the REST-backed service is protected the service needs to be configured differently. In most cases the Authorization header needs to be set. Flowable offers an easy way to configure the Authorization header for HTTP Basic and HTTP Bearer authorizations by configuring the authorization for a model or an operation.

note

The images below are showing the configuration on the definition level (applicable for all operations). However, each operation can be configured separately (or overwrite the configuration from the model) if needed.

Basic Authorization

Rest Service Definition Basic Authorization

Bearer Authorization

Rest Service Definition Bearer Authorization