Serverless Architecture

  • What is Serverless Architecture?

    Serverless architecture allows developers to build and run services without managing infrastructure. Cloud providers handle provisioning, scaling, and maintenance, enabling developers to focus on application code.

  •                 graph TD
                        A[Developer writes code as functions] --> B[Triggers set up]
                        B --> C[Functions deployed to Cloud Provider]
                        C -->|Event Triggered| D[Function executed on server]
                        D -->|Server auto-scaled if needed| E[Result returned]
                
  • Common Use Cases

    1. Web Applications: Use serverless functions to handle user requests.
    2. Data Processing: Process files, logs, or streams in real-time.
    3. Chatbots and APIs: Build chatbots or APIs with serverless backends.
    4. IoT Applications: React to IoT device events without maintaining servers.
  • How It Works

    Cloud providers execute application functions triggered by events. If no server is running, a new server is spun up automatically to execute the function, abstracting server management from developers.

  • flowchart TD User[User Request] --> Frontend[Web/Mobile App] Frontend --> API[API Gateway] API --> Function[Serverless Function] Function --> Database[Database/Storage] Function -->|Optional| Notification[Send Notifications] Database --> Function Function --> Frontend
    1. Frontend: A web or mobile interface sends requests (via HTTP or APIs).
    2. Trigger: Events such as API calls, database updates, or file uploads activate the serverless function.
    3. Backend Logic: Functions handle the specific logic, e.g., processing a file, querying a database, or sending notifications.
    4. Output: Results are sent back to the client or passed to another function.
  • sequenceDiagram participant User as User participant App as Frontend App participant API as API Gateway participant Cloud as Cloud Provider participant DB as Database User->>App: Send Request App->>API: API Call API->>Cloud: Trigger Serverless Function Cloud->>DB: Query/Store Data DB-->>Cloud: Data Response Cloud-->>App: Send Output App-->>User: Display Result
  • Example of Serverless Workflow

    1. A user uploads a file via a web interface.
    2. The upload event triggers a function to process the file.
    3. The processed file is stored in a database or cloud storage.
    4. A notification is sent to the user upon completion.
  • Key Model: Function as a Service (FaaS)

    FaaS enables developers to write discrete functions for specific tasks. These are deployed along with triggers to a cloud provider, simplifying deployment and scaling.

  • Benefits

    • No infrastructure management
    • Auto-scaling
    • Pay-per-use cost model

1. What is Spring Cloud Function?

Spring Cloud Function is a framework that allows you to develop serverless applications in Java using Spring Boot. It provides a simple programming model for writing functions that can be triggered by events such as HTTP requests, database changes, or messaging.

2. Setup the Spring Boot Project

  • Project: Maven (or Gradle)
  • Dependencies:
    • Spring Web
    • Spring Cloud Function Web
    • (Optional) AWS Lambda for serverless deployment
	<dependencies>
    <!-- Spring Boot Web for REST API -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- Spring Cloud Function for serverless support -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-function-web</artifactId>
    </dependency>
    
    <!-- Optional: AWS Lambda support 
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-aws-lambda</artifactId>
    </dependency>
	-->
</dependencies>
a simple function that converts a string to uppercase. This function will be triggered via an HTTP request.

Step 1: Define the Function

Create a class UppercaseFunction.java that implements the Function interface from Java's java.util.function package.
	
package com.example.serverless;

import org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler;
import org.springframework.stereotype.Component;

import java.util.function.Function;

@Component
public class UppercaseFunction implements Function<String, String> {

    @Override
    public String apply(String input) {
        return input != null ? input.toUpperCase() : "Input is null";
    }
}
  • The function takes a string as input and returns the uppercase version.
  • If the input is null, it returns "Input is null."

Step 2: Create Function Configuration

In Spring Cloud Function, you can define beans for each function.
The function will be mapped to an endpoint automatically by Spring Cloud Function Web.

package com.example.serverless;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FunctionConfig {

    @Bean
    public UppercaseFunction uppercaseFunction() {
        return new UppercaseFunction();
    }
}

Step 3: Create the Spring Boot Application


package com.example.serverless;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

You can bluid the application and run it manually


Build application- mvn clean install


Run application- java -jar target/yourapp.jar

step 4 Exposing the Function via HTTP

Spring Cloud Function automatically maps functions to HTTP endpoints. By default, it uses the function name as the endpoint.

GET http://localhost:8080/uppercaseFunction/hello
Result:

HELLO
you can use GET , POST

Example 2: JSON Parsing

Let’s create a function that processes JSON data:

package com.example.serverless;

import java.util.function.Function;

@Component
public class GreetingFunction implements Function<Person, String> {

    @Override
    public String apply(Person person) {
        return "Hello, " + person.getName() + "!";
    }
}
Person.java :

package com.example.serverless;

public class Person {
    private String name;

    // Getters and setters

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
add it to FunctionConfig.Java

package com.example.functionTestApp;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FunctionConfig {

    @Bean
    public UppercaseFunction uppercaseFunction() {
        return new UppercaseFunction();
    }
    
   
    
    @Bean
    public GreetingFunction greetingFunction() {
        return new GreetingFunction();
    }
    
    
    
}
Test it: POST: http://localhost:8080/greetingFunction

{
    "name": "John"
}
Response:

Hello, John!