Skip to main content
Version: 1.19 (unreleased)

Function Provider SPI

Functions can be invoked in expressions and unary tests. The engine includes some predefined built-in functions.

Own functions can be defined in two ways:

  • declaring them in an expression (e.g. a context)
  • via the function provider SPI

Using the SPI, the function can be implemented in Scala/Java and is not limited by FEEL. So, it's possible to use language features or libraries.

Create a sub-class of org.camunda.feel.context.CustomFunctionProvider and implement the method getFunction() which returns the function for the given name. If a function can have different parameters (i.e. different parameter count) then override getFunctions() instead.

class CustomScalaFunctionProvider extends CustomFunctionProvider {

def getFunction(name: String): Option[ValFunction] = functions.get(name)

def functionNames: Iterable[String] = functions.keys

val functions: Map[String, ValFunction] = Map(
"incr" -> ValFunction(
params = List("x"),
invoke = { case List(ValNumber(x)) => ValNumber(x + 1) }
)
)

}

The function must be of type ValFunction. It contains

  • params - list of the named parameters of the function
  • invoke - business logic as function which takes the arguments and returns the result. The order of the arguments is defined by the parameter list.
  • hasVarArgs - if true the function can have variable arguments for the last parameter. The last argument is of type list.

Register the Function

Depending how the FEEL engine is used, the function provider can be passed directly on creation, or is loaded via Java ServiceLoader mechanism (by using the SpiServiceLoader.loadFunctionProvider() as function provider).

In the second case, create a new file org.camunda.feel.context.CustomFunctionProvider in the folder META-INF/services/. It must contain all function providers by their full qualified name.

org.camunda.feel.example.context.CustomScalaFunctionProvider
org.camunda.feel.example.context.CustomJavaFunctionProvider