Developing Server-less applications with Spring Boot
This article consists of 4 parts-
- What is Server-less Architecture?
- Key benefits of Server-less Architecture.
- What is Spring Cloud Function?
- Developing Server-less application with Spring Cloud Function.
What is Server-Less Architecture?
Let’s think about a development approach where we neither need to configure an infrastructure nor maintain it. However it’s not possible!
As long as we need to host our application in a server, we need to configure and maintain infrastructure as well.
# But what if the infrastructure is configured and maintained by someone else, we just need to develop and deploy our application?
# What if we don’t need to pay for the server just because it is running, rather pay only for the application usage?
That is Server-less Architecture.
Server-less architecture is an execution model of Cloud Computing where the cloud provider-
- Runs the server and hosts the application.
- Dynamically allocates machine resources to the application.
- Charges application cost as per resource usage.
Key benefits of Server-less Architecture
- No Server or OS to configure.
- Can be scaled automatically. Or can achieve custom scalability very easily. So no need to create any specialized scalable architecture.
- Server-less application has built in availability and fault tolerance. So no need to have any specialized infrastructure.
- No idle capacity. Pay only for use.
What is Spring Cloud Function?
# Spring Cloud Function is a project by Spring Pivotal team which provides-
- All server-less benefits to an application.
- Spring features like- dependency injection, auto-configuration.
- Build tools features like- testing, continuous delivery, run locally.
- Adapters for Cloud providers like- AWS Lambda, Azure etc.
# Spring Cloud Function aims to achieve some high level goals like-
- Enable Spring Boot features on cloud providers.
- Use function to implement business logic. Use the same function as RESTful service, stream processing app or a task.
- Separate business logic development from specific runtime target.
- Establish a common programming model among server-less providers.
For more detail check here-
Developing Server-less application with Spring Cloud Function
I hope by now we have clear idea about what Server-less application is. Now let’s jump into the development of a simple server-less application with Spring Boot and Spring Cloud Function.
We will create a Standalone Web application.
1. Create project
To start with, we will need to create a Spring Boot project. We can use Spring Initializr to create a simple project.
2. Add dependencies
Now we need to add spring-cloud-starter-function-web dependency. It will act as the local adapter and will introduce necessary dependencies to the project to run function in local environment.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-function-web</artifactId>
</dependency>
3. Declare Function With @Bean
Function can be created in class body. Annotating method with @Bean will expose the function as an endpoint.
# Let’s create 3 functions, and check how they work when exposed as endpoints.
@Component
public class Controller {
@Bean
public Function<String, String> function() {
return input -> input;
}
@Bean
public Consumer<String> consume() {
return input -> {
System.err.println("Input-" + input);
};
}
@Bean
public Supplier<String> supply() {
return () -> "Hello from Supplier";
}
}
Spring Cloud Function provides 3 types of wrapper for @Bean.
- Function- accepts input and returns output.
- Consumer- accepts input, does not return anything .
- Supplier- does not accept input, only returns output.
# Now we will run the application and check the endpoints.
Build application- mvn clean install
Run application- java -jar target/spring-cloud-function-0.0.1-SNAPSHOT.jar
# Check endpoints-
Function-
$ curl http://localhost:8080/function/SpringCloud
> SpringCloud
What do we find here?
- String parameter “SpringCloud” has been passed to the method function().
- Method returned a String response.
Consumer-
$ curl http://localhost:8080/consume/SpringCloud
What do we find here?
- As Consumer does not not return any output, endpoint did not send any response.
- Console printed response as per method logic.
Supplier-
$ curl http://localhost:8080/supply
> Hello from Supplier
What do we find here?
- As Supplier does not accept any input, nothing was passed to the endpoint.
- Endpoint sent a String response.
# What is common for all 3 methods is-
- All @Bean annotated method has been exposed as HTTP endpoint.
- Method name is endpoint URI.
4. Declare Function With Class
Function can also be declared by creating a class that implements the Function Interface.
# Let’s keep the thing simple and create a Function that will-
- accept a String input.
- return Integer as output.
a. Create class-
public class GetLength implements Function<String, Integer> {
@Override
public Integer apply(String value) {
return value.length();
}
}
b. Classpath scanning-
For class based Function we need to enable classpath scanning. Add below code to application.properties
file-
spring.cloud.function.scan.packages=com.spring.serverless
# Re run the application and check the endpoint-
$ curl http://localhost:8080/getLength/SpringCloud
> 11
What do we find here?
- String parameter “SpringCloud” has been passed to the endpoint.
- Endpoint returned input length Integer as response.
- Class name is endpoint URI.
Pretty simple, right? Just create a @Bean annotated function, or a “Function” implemented class. And you will get a fully functional endpoint, with all Spring features available.
# But practically our endpoints would need more flexibility with POJO and JSON support. So lets create another endpoint which-
- accepts JSON data as input maps that it into a model.
- and returns JSON output with model.
a. Create POJO
public class Model {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
b. With @Bean- Extend Controller class with a reverseString() function
...@Bean
public Function<Model, Model> reverseString() {
return model -> {
String reverseString = new StringBuilder(model.getValue()).reverse().toString();
model.setValue(reverseString);
return model;
};
}
c. With Class- Create a class
public class Uppercase implements Function<Model, Model> {
@Override
public Model apply(Model model) {
String upperCase = model.getValue().toUpperCase();
model.setValue(upperCase);
return model;
}
}
# Run the application and check the endpoints-
Reverse String-
$ curl -d '{"value": "Spring Cloud"}' -H "Content-Type: application/json" -X POST http://localhost:8080/reverseString
> {"value":"duolc gnirpS"}
Uppercase-
$ curl -d ‘{“value”: “New User”}’ -H “Content-Type: application/json” -X POST http://localhost:8080/uppercase
> {“value”:”NEW USER”}
What do we find here?
- JSON data for Model has been passed to the endpoint.
- Endpoint sent a JSON response with same POJO.
Check this Github link for Sample application of Spring Cloud Function.
What this article does not cover
- When to use- Server-less application is not a one stop solution for all types of web application. This post does not cover when to use Server-less architecture and when not to.
- Deploy to AWS lambda- AWS Lambda is a widely used Cloud provider. Our application needs some changes before we deploy it to AWS Lambda.
In my next article I will try to cover those areas.
Conclusion
Server-less architecture can reduce development time and cost by eliminating the need of configuring and managing a infrastructure.
Though still growing up, Spring Cloud Function is a powerful tool for decoupling the business logic from any deployment profile. It facilitates developer to use the same code as web endpoint, cloud function or a stream.
Visit our website to learn more about us:
www.monstar-lab.co.bd