Master Serverless with Spring Cloud Function: A Hands‑On Guide
This tutorial introduces Spring Cloud Function, explains its core concepts and benefits for serverless development, and walks through a complete example—including configuration, code snippets, HTTP endpoints, function composition, custom routing, and deployment—so readers can quickly build and test function‑based applications.
Environment: SpringBoot 2.7.15 + Spring Cloud 2021.0.8.
1. Introduction
Spring Cloud Function is a project with the following high‑level goals:
Enable business logic implementation through functions.
Decouple the development lifecycle of business logic from any specific runtime target, allowing the same code to run as a web endpoint, stream processor, or task.
Provide a unified programming model across serverless providers and support independent execution (locally or in PaaS).
Expose Spring Boot features (auto‑configuration, dependency injection, metrics) on serverless platforms.
It abstracts transport details and infrastructure, letting developers keep familiar tools and focus on business logic. Example:
<code>@SpringBootApplication
public class Application {
@Bean
public Function<Flux<String>, Flux<String>> uppercase() {
return flux -> flux.map(value -> value.toUpperCase());
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
</code>The above is a regular Spring Boot application, so it can be built, run, and tested locally or in CI just like any other Spring Boot app. The Function comes from java.util and Flux is a Reactive Streams publisher, accessible via HTTP or messaging.
Spring Cloud Function offers four main capabilities: it wraps @Bean functions of type Function, Consumer, and Supplier as HTTP endpoints or message listeners/publishers (e.g., RabbitMQ, Kafka); supports reactive, imperative, or mixed programming styles; allows function composition and adaptation; and provides transparent type conversion for inputs and outputs.
2. Example Application
The Function can be automatically exported as an HTTP endpoint. When the spring-cloud-function-web module is on the classpath, a MVC endpoint (default path "/") is created, exposing the function name as part of the URL. Supported content types are plain text and JSON.
Typical request patterns:
GET /{supplier} – returns 200.
POST /{consumer} – accepts JSON or text, returns 202.
POST /{function} – accepts JSON object or text, returns 200.
GET /{function}/{item} – returns 200.
Dependency configuration:
<code><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-web</artifactId>
</dependency>
</code>GET /{supplier}
<code>@Bean
public Function<Flux<String>, Flux<String>> uppercase() {
return flux -> flux.map(value -> value.toUpperCase());
}
</code>Result:
POST /{consumer}
<code>@Bean
public Consumer<Person> consumer1() {
return person -> System.out.println("Blocking call: " + person);
}
</code>Result:
Console output:
Composite Functions
Define multiple functions:
<code>@Bean
public Function<Flux<String>, Flux<String>> uppercase() {
return flux -> flux.map(v -> v.toUpperCase());
}
@Bean
public Function<Mono<String>, Mono<String>> reverse() {
return input -> input.map(v -> new StringBuilder(v).reverse().toString());
}
@Bean
public Function<Mono<String>, Mono<String>> length() {
return input -> input.map(v -> v + " - " + v.length());
}
</code>Compose them via URL:
<code>http://localhost:8080/[uppercase][,reverse][,length]
</code>You can call a single function, two functions separated by commas, or three functions in the same request.
Exclude a Function
<code>spring:
cloud:
function:
ineligible-definitions:
- uppercase
</code>Functions listed under ineligible-definitions will not be exposed.
Custom Routing
<code>@Bean
public MessageRoutingCallback customRouter() {
return new MessageRoutingCallback() {
@Override
public FunctionRoutingResult routingResult(Message<?> message) {
return new FunctionRoutingResult((String) message.getHeaders().get("func_name"));
}
};
}
</code>The header func_name determines which function is invoked.
Finished!
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.