9.1.2 FunctionBean

This section applies to Java & Kotlin functions - for functions written in Groovy, see Groovy Functions

To write your function’s behavior, annotate your class with the @FunctionBean annotation. Your class must also implement one of the interfaces from the java.util.function package.

If you have the Micronaut CLI installed you can quickly create a Java function with mn create-function hello-world or mn create-function hello-world —lang kotlin for Kotlin

The following examples implement Java’s Supplier functional interface.

Example Java Function

  1. package example;
  2. import io.micronaut.function.FunctionBean;
  3. import java.util.function.Supplier;
  4. @FunctionBean("hello-world-java")
  5. public class HelloJavaFunction implements Supplier<String> {
  6. @Override
  7. public String get() { (1)
  8. return "Hello world!";
  9. }
  10. }
1Override the get method of Supplier to return the response from your function.

Alternatively you can also define a Factory that returns a Java lambda:

Example Java Function as a Lambda

  1. package example;
  2. import io.micronaut.context.annotation.*;
  3. import io.micronaut.function.FunctionBean;
  4. import java.util.function.Supplier;
  5. @Factory (1)
  6. public class MyFunctions {
  7. @FunctionBean("hello-world-java")
  8. public Supplier<String> helloWorld() { (2)
  9. return () -> "Hello world!";
  10. }
  11. }
1A Factory bean is defined
2The @FunctionBean annotation is used on a method that returns the function.

If you are using Kotlin then process is exactly the same:

Example Kotlin Function

  1. package example
  2. import io.micronaut.function.FunctionBean
  3. import java.util.function.Supplier
  4. @FunctionBean("hello-world-kotlin")
  5. class HelloKotlinFunction : Supplier<String> {
  6. override fun get(): String { (1)
  7. return "Hello world!"
  8. }
  9. }
1Override the get method of Supplier to return the response from your function.

The following table summarizes the supported interfaces:

Table 1. Functional Interfaces
InterfaceDependency

Supplier

Accepts no arguments and returns a single result

Consumer

Accepts a single argument and returns no result

BiConsumer

Accepts two arguments and returns no result

Function

Accepts a single argument and returns a single result

BiFunction

Accepts two arguments and returns a single result

In addition, functions have an input and/or an output. The input is represented by the accepted argument and represents the body consumed by the function and the output is represented by the return value of the function. The input and the output should be either a Java primitive or simple type (int, String etc.) or a POJO.

Often, you want to accept a POJO and return a POJO. Use java.util.function.Function to accept a single argument and return a single result.

  1. import io.micronaut.function.FunctionBean;
  2. import java.util.function.Function;
  3. @FunctionBean("isbn-validator")
  4. public class IsbnValidatorFunction implements Function<IsbnValidationRequest, IsbnValidationResponse> {
  5. @Override
  6. public IsbnValidationResponse apply(IsbnValidationRequest request) {
  7. return new IsbnValidationResponse();
  8. }
  9. }

A single project can define multiple functions, however only a single function should be configured for execution by the application. This can be configured using the micronaut.function.name property in application.yml:

Configuring the Function Name to Execute

  1. micronaut:
  2. function:
  3. name: hello-world-java

Alternatively you can specify the value when running your function (for example in the Dockerfile) either as an environment variable:

Specifying the Function to Execute as a Environment variable

  1. $ export MICRONAUT_FUNCTION_NAME=hello-world-java
  2. $ java -jar build/libs/hello-world-function-all.jar

Or as a system property:

Specifying the Function to Execute as a System property

  1. $ java -Dmicronaut.function.name=hello-world-java -jar build/libs/hello-world-function-all.jar