Flow language behavior and syntax

This article provides detailed information about the flow language behavior and syntax.

The following symbols are used in the descriptions provided in this article:

+
At least one
?
Zero (0) or one (1)
*
Zero (0) or more of a particular construct is allowed.

Any construct without these is treated as mandatory.

Using processes

You can use the process element to define a REST work flow. Processes are named and contain a set of activities that capture the logic of the work flow. A process can also define global data items (variables) and declare a preference for a particular expression language to be used for data access and expressions. Currently, Groovy and a subset of Javascript™ (side effect free expressions) are supported.

A process interacts with Web-based services and clients over HTTP or SMTP. It, therefore, can handle data of the following different content types:

  • URL-encoded parameters
  • Form data
  • XML
  • JSON
  • Plain text

The following example shows the process element syntax:

<process name="NCName" expressionLanguage="NCName"? xmlns:customNamespace="URI"* >
   <variable>...</variable>* 
   activity+
</process>
  • The process name is mandatory.
  • The process expressionLanguage is optional. By default, it is Groovy.
  • The custom namespaces could be defined in <process > for further usage, for example, specify the XPath in XML or Feed operators.
  • In the flow namespace context, the following custom namespaces are defined:
    • xmlns:atom="http://www.w3.org/2005/Atom"
    • xmlns:zero="http://www.projectzero.org/assemble/flow"

Using variables in a process

You can use variables in a process to identify named data items and documents. You can declare a variable at the top of the process; otherwise, it is defined on the first use. An explicitly declared variable contains the following elements:

  • a name
  • an optional content-type
  • an optional initializer (from)

Any expression in the language can refer to (read) a variable. A variable can be externally configured.

The following types of variables can be used:

Activity output
Variables named by the name of each activity in the process. They are implicitly created and initialized to contain the output data (if any) of the activity. These variables are to be used as read-only containers in which the activity data is made available. They are never declared and their type is determined by the data returned by the corresponding activity.
Activity exception
Variables named after each activity in the process followed by _Exception. They are implicitly created and initialized if the activity fails, and they contain data about the error, including an optional errorCode and message.
Free
Variables containing any other data items used by the process. Typically, they contain data needed to support the work flow logic execution.

The following example shows the variable declaration syntax:

<variable name="VariableName"/> 

The name element is mandatory.

Expressions

Several activities use expressions, such as to define a condition on a loop. An expression can refer to any of the variables of the process, regardless of the inputs for the activity. Expressions must be side-effect free and have read-only access to process variables and other states.

Groovy Expression Support

You can specify Groovy as the expression language of the flow, and access the global context content, like request.params.num[0], which is consistent with the IBM® WebSphere™ runtime Groovy support, as shown in the following example:

<process name="add" expressionLanguage="Groovy">
   <receiveGET name="addRcv"/>
   <replyGET name="addReply"> 
     <control source="addRcv"/>  
     <input value="${request.params.num[0].toInteger() + request.params.num[1].toInteger()}"/>
   </replyGET>
</process>

For more information about Groovy support, see the bindings information about Groovy handlers and global context. By default, the WebSphere sMash runtime binds the variables to access the global context before invoking a script.

app
Bound to the app zone in the global context.
config
Bound to the configuration zone.
event
Bound to the event zone.
headers
Bound to the request zone.
request
Bound to the request zone.
user
Bound to the user zone.

A Groovy expression in flow supports the DOMCategory in which you can access a DOM node of XML data over a helper method that is built-in in a compact syntax. The namespace is declared in the flow description file and can be used in the DOM node with namespace. This is shown in the following example that is accessing an extension element in the Yahoo!® music feed:

<process name="yahooMusic"
   xmlns:media="http://search.yahoo.com/mrss"
   xmlns:atom="http://www.w3.org/2005/Atom">

   <feed name="topAlbums" url="http://rss.music.yahoo.com/charts/rssTopAlbums.xml" />
   ...
   <!-- reply the credit text value  -->
   <replyGET name="reply">
      <input value="${topAlbums.entry[0].'media:credit'.text()}"/>
   </replyGET>
</process>

Activities

Activities are the individual steps in running a REST process. The language supports several types of specialized activities, performing specific function, and a general purpose activity to run arbitrary code as part of the process.

The set of specialized activities is an extensible set. You, or any member of your development community, can add new types of activities.

All activities share a basic set of common elements:

<[activity-type] name="NCName" extension-attributes>
  <control source="NCName" transitionCondition="boolean-expr"? error="yes|no"?/>*
  <input name="NCName"? 
         value="value"?/>*
</[activity-type]>
  • All activities have mandatory names that must be unique. The name of an activity can be used for monitoring, modeling, and referencing from other parts of the process, if required.
  • Activities can also be the targets of links.
  • An extension activity cannot access process state or directly affect the navigation.

A link represents a runtime dependency between two activities in which the target activity cannot start until the source activity has completed and the relevant conditions are met. A link can not create a loop and can not cross the boundary of a while and for-each construct. See the Running processes and activities section for an explanation of link semantics. The default value of the condition is true().

The link is syntactically placed in the target activity using the <control> element. An input element, the value of which is exactly the name of one activity, serves as combination of both an input definition and a control link. This is referred to as the control shortcut.

<control source="NCName" transitionCondition="boolean-expr" error="yes|no"?/>       

In this example, the following elements are shown:

source
The name of an activity that is the source of the link.
transitionCondition
The condition that determines if this link is followed. The default value is true.
error
States whether this is to be treated as an error link. If it is true, then the link always fires false unless the activity that is the source of the link fails. If it fails, then all links with error=no fire false. On the other hand, the links that have an error value of yes are traversed with the value of evaluating their transitionCondition. (Recall that its default value is true). The default value of error is no.

Activity data

One implicit output variable, in which the output data is stored, is created for each activity. The name of this variable is [activity-name]. This variable is only allowed to write by the activity itself. An activity can specify a different variable by the outputVariable attribute to which its data is also copied and the shared writing is allowed. If an activity is disabled, its output was never created so the value of its output variable is null. The input of an activity, A, that takes input data is defined by the list of <input> elements of the activity.

One implicit exception variable named with [activity-name]_Exception is also created for each activity if the activity fails. The value of this variable provides information about the error that caused the failure.

<input name="NCName"? value="value"? >complex value?</input>

If the input of an activity, A, refers to an activity name B, then this provides a control shortcut whereby A waits for B to complete AND takes its output data as one of its inputs.

If the control shortcut is used, then you can also use the error shortcut, by using the variable of [source-activityName]_Exception. The resulting behavior is similar to the error being set to yes on a control element. That is, the target activity acts as a fault handler if an error occurs when running the source-activity.

An input of an activity in a <while> cannot use the control shortcut (input refers to an activity that is outside <while> or <for-each>). This rule prevents surprising behavior that is difficult to anticipate by developers.

You can use the output of another activity directly without creating a one-to-one control dependency, if there is a path between the two activities. To use the output of another activity (or any other variable) without adding a link (for example, you know there is a path already), you can refer to the output variable of the activity, as shown in the following example:

<POST name="..." target="...">
   <control source="someActivity"/>
   <input value="${anotherActivityName}"/>
</POST>

Version 1.0.0.3.25591