What is Spring Cloud Functions ?
Spring Cloud Functions is a project done by Spring team at Pivotal which makes every service to be exposed as a function to the outside world, unlikely as in REST endpoint. This can be deployed as a server less as well.
A function can produce, consume, filter, aggregate or oragize messages coming from different sources and push to different destinations.
Using Spring Cloud Function you can create REST endpoints without a URL mapping. We can expose @Beans of type Function, Consumer or Supplier as Rest endpoints:
//@Component //This also works @Configuration public class BookController { @Bean public Function<String, String> reverse() { return (input) -> new StringBuilder(input).reverse().toString(); } @Bean public Supplier<Book> getBook() { return () -> new Book(101, "Core Java"); } @Bean public Consumer<String> printMessage() { return (input) -> System.out.println(input); } }
Lets create a spring boot project for the same.
Create a spring boot project from Spring Initializr with below dependencies:
- Function
- Spring Web (required to access the endpoints from browser)
- Lombok
Add a controller class:
//@Component //This also works @Configuration public class BookController { @Bean public Function<String, String> reverse() { return (input) -> new StringBuilder(input).reverse().toString(); } @Bean public Supplier<Book> getBook() { return () -> new Book(101, "Core Java"); } @Bean public Consumer<String> printMessage() { return (input) -> System.out.println(input); } }
Add a model class:
@Data @AllArgsConstructor @NoArgsConstructor public class Book { private int id; private String name; }
Thats all…
Start the application.
Now lets call one of the end points. What should be the endpoints ? If you see the controller class there are some methods, one of them is reverse() method. So this would be one of the endpoint and it would be like below:
http://localhost:8080/reverse/
Lets call the above url by passing a string to it so that it would reverse that string.
As you can see in the above page it returns the reversed string.
Source code of the above code: https://github.com/heapsteep/spring-cloud-function-2
Lets now see another example where we will deploy the above Spring behaviour to AWS Lambda.
Spring Cloud Function AWS Lambda:
In this tutorial we will see AWS lambda spring boot example.
Lets create a blank spring boot project (without adding any dependency) from Spring Initializr.
Since this has to be deployed as Lambda project it has to be as small as possible. So we will be very choosy while adding dependencies.
In the above Spring Cloud Function example we had added the dependency from Spring Initializr, but here we will addd it manually as its not available on Spring Initializr. This dependency will be specific to AWS only:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-function-adapter-aws</artifactId> </dependency>
Then for Lambda specific dependency we will add below things. The same we had also used in the AWS Lambda with Java tutorial.
<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>2.0.2</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.1.0</version> <scope>provided</scope> </dependency>
As done in the same AWS Lambda with Java tutorial, you need to make it a fat jar by adding Shade plugin.
And add spring-boot-thin-layout dependency to make it a thin and lightweight jar:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot.experimental</groupId> <artifactId>spring-boot-thin-layout</artifactId> <version>1.0.10.RELEASE</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <!-- <version>3.2.2</version> --> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <!-- <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>aws</shadedClassifierName> --> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Then write a empty handler class by extending from SpringBootRequestHandler:
public class MyHandler extends SpringBootRequestHandler<String,String> { }
Have the same controller and model class that we used in the previous example above.
//@Component //This also works @Configuration public class BookController { @Bean public Function<String, String> reverse() { return (input) -> new StringBuilder(input).reverse().toString(); } @Bean public Supplier<Book> getBook() { return () -> new Book(101, "Core Java"); } @Bean public Consumer<String> printMessage() { return (input) -> System.out.println(input); } }
@Data @AllArgsConstructor @NoArgsConstructor public class Book { private int id; private String name; }
clean package the project.
Now we need to upload the fat jar to the AWS environment in the form of a Lambda.
To upload the Spring Cloud Function as Lambda in AWS you can follow the same process that we had mentioned in this tutorial: AWS Lambda with Java. Here you don’t have to mention the method name after the class name unlikely we did in that example and you have to mention the FUNCTION_NAME.
P.S.: You can give any Java version. We have developed the application in Java 8 and we are giving here Java 11.
Go to Configuration -> Environment Variables -> Add Environment Variables
Add the methods that we had mentioned as @Bean in the controller class:
Create a test event like below:
Once you run the test you can see the reverse output:
Thats it !!…