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.