Spring Cloud Function is a new project from the Spring team at Pivotal that aims to promote the function as the primary unit of development work. The project also provides a common model for deploying function-based software across a variety of deployment platforms, including FaaS (function as a service) platforms like Amazon’s AWS Lambda.
In common with the other serverless models, the project aims to make the function the primary concept a developer works on. A second important element of the project is the decoupling of business logic from deployment profile. While business logic is implemented as functions, the same code can be given a deployment profile that exposes the function as a RESTful service, a stream processing app (such as Spring Cloud Data Flow), or a finite task. This means that the same individual function can be deployed as a standalone app or deployed to a FaaS platform. So far the team has provided adaptors for AWS Lambda and Apache OpenWhisk, with more promised for other serverless platforms like Google Cloud Functions and Azure Functions once they provide support for Java.
While the clean abstraction and obvious cost-benefits of a platform like AWS Lambda are attractive to many developers, a key concern, particularly for the enterprise, has been the risk of vendor lock-in due to the inclusion of framework-specific code in the source.
As serverless expert Mike Roberts writes on Martin Fowler’s website:
Depending on the circumstances, [serverless FaaS systems] can significantly reduce operational cost and complexity at a cost of vendor dependencies and (at the moment) immaturity of supporting services.
Spring Cloud Function offers to mitigate this by introducing deployment-platform dependencies at the package phase in the delivery pipeline. This means that a developer can implement a function in isolation (including creating unit tests), concerned only with the logic and the input and output parameters of the function. The function is then packaged with the dependencies that allow it to run in the target environment.
Mark Fisher, the Spring Cloud Function project lead, told InfoQ:
For serverless, we want to improve the experience for Java developers, since portability, and consistency are big challenges.
At the core of the project is the promotion of a programming model based on functions, as opposed to the slightly more familiar Spring convention of POJOs. Those who have already dipped their toes into the serverless world will recognise this model, where developers have no concept of the underlying infrastructure or framework, and simply concentrate on the implementation of business logic rather than boilerplate or other “plumbing” code. With Spring Cloud Function, business logic is developed using implementations of the core interfaces defined in the java.util.function package: Function, Consumer, and Supplier.
In this very simple example, we can create a class that implements the Function Interface:
import java.util.function.Function;
public class LengthCounter implements Function<String, Integer> {
@Override
public Integer apply(String name) {
return new Integer(name.length());
}
}
The magic is then applied via classpath scanning enabled by the @FunctionScan annotation:
@FunctionScan
@SpringBootApplication
public class ExampleSpringFunctionApplication {
...
Alternatively, functions can be declared in class bodies and annotated with @Bean:
@Bean
public Function<String, Integer> lowercase() {
return flux -> flux.map(value -> value.toLowerCase());
}
If this approach is taken, there is no need for the @FunctionScan.
Functions are packaged as Jar files that are wrapped with the necessary configuration and adaptors by the appropriate deployment profiles for the target deployment platform.
Mark Fisher told us:
Apart from serverless, we want to promote the simplicity of functions as dev unit, and portability across a full range of deployment targets.
Developers concentrate on creating business-focused functions, using the tools, processes and utilities they are familiar with from the Spring Boot ecosystem (e.g. automated testing, auto-configuration, dependency injection, or metrics), while the underlying transport details, infrastructure, and deployment frameworks are abstracted away.
The project is in its early stages but the folks at Spring promise more to come, such as integration with Fission and other Kubernetes-based serverless platforms, as well as closer integration with the new version of Spring Cloud Data Flow.