Spring Cloud Function: Write Once, Deploy Anywhere
Spring Cloud Function is a project in the Spring Cloud ecosystem that gives you a consistent programming model for building cloud-native functions. The core idea is simple: write a Java function once, then deploy it to AWS Lambda, Azure Functions, Google Cloud Functions, or run it as a regular Spring Boot web app — without changing your business logic.
This article walks through the basics of Spring Cloud Function, why it’s useful, and a concrete example you can run locally or push to AWS Lambda.
Why Use Spring Cloud Function?
Cloud portability. Your function code has zero cloud-specific imports. The framework handles the adapter layer for each cloud provider, so switching from AWS to Azure doesn’t require rewriting your handlers.
Full Spring ecosystem access. You can inject Spring Data repositories, use Spring Security, wire in Spring Cloud Stream — all the things you’d expect in a standard Spring Boot application work here.
Function composition. Spring Cloud Function lets you chain functions together declaratively. Two functions uppercase and trim can be composed into trim|uppercase via configuration, with no glue code.
Event-driven by design. The model maps naturally to event-driven architectures. Functions consume events, transform them, and produce output — whether that input comes from an HTTP request, a Kafka topic, or an SQS queue.
Getting Started
Step 1: Set Up the Project
Create a new Spring Boot project at https://start.spring.io/ and add these dependencies:
- Spring Web
- Spring Cloud Function
- Spring Boot Actuator (optional)
Your pom.xml dependencies section should include:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-web</artifactId>
</dependency>
Step 2: Define the Function
Spring Cloud Function works with three standard Java functional interfaces: Function, Consumer, and Supplier. You register them as Spring beans, and the framework does the rest.
Here’s a basic Function that converts a string to uppercase:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import java.util.function.Function;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public Function<String, String> uppercase() {
return value -> value.toUpperCase();
}
}
Spring Cloud Function automatically discovers beans that implement Function, Consumer, or Supplier and exposes them.
Step 3: Test the Function Locally
Add the web starter if you haven’t already:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-function-web</artifactId>
</dependency>
Start the application and call the function over HTTP:
curl -H "Content-Type: text/plain" -d "hello" http://localhost:8080/uppercase
Expected response:
HELLO
The function name becomes the URL path. If you defined a bean called uppercase, it’s available at /uppercase.
Deploying to AWS Lambda
Add the AWS Adapter
Include the AWS adapter dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-aws</artifactId>
</dependency>
Package and Deploy
Build the JAR:
mvn clean package
When uploading to AWS Lambda, set the handler to:
org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest
This handler scans your application context for Function, Consumer, and Supplier beans and wires them up automatically. You don’t need a separate handler class for each function.
One note: if you go the GraalVM native image route (compiling to an arm64 ELF binary), you skip the handler configuration entirely — the binary exposes all endpoints on startup. That’s a larger topic outside the scope of this walkthrough.
A working example is available in the katyella/spring-examples repository.
Conclusion
Spring Cloud Function gives you a clean way to write serverless Java without tying your code to a specific cloud provider. The function interfaces are standard Java — no AWS SDK imports, no Azure-specific annotations. The adapters handle that translation, so your business logic stays portable.
For simple transformations and event processing, this model works well. Where it gets more interesting is function composition and integration with Spring Cloud Stream, which lets you connect functions directly to message brokers. If you’re building event-driven microservices on top of Spring Boot, Spring Cloud Function is worth adding to your toolkit.
Related Articles
- Spring Cloud Overview: Building Resilient Microservices — The full Spring Cloud ecosystem that Spring Cloud Function fits into.
- GraalVM Native Image with Spring Boot — Compile your Spring Cloud Functions to native images for faster cold start times on AWS Lambda.
- Spring Cloud Task: Short-Lived Microservices — Another approach to short-lived, discrete units of work in Spring Cloud.
- Spring Boot Microservices Architecture Patterns — See how serverless functions fit into larger microservices designs.