Is there anyway we can use Spring Cloud Functions + AWS Lambda adapter to process http file uploads? - spring-boot

I am new to AWS and FAAS. My work place is interested in processing HTTP file upload with AWS Lambda and Spring Boot. A quick research led me to Spring Cloud Functions + AWS Lambda adapter; however, documentation doesn't cover anything related to HTTP file uploads, so I wonder if it is possible to do that with Spring Cloud Function or I have to fallback to AWS Lambda Spring Boot integration (https://github.com/awslabs/aws-serverless-java-container)?
Thanks in advance for your kind enlightenment!

AWS lambda can be triggered in many ways like API gateway, S3Event, SNS notification and SQS. API gateway integrates lambda with HTTP end points. API gateway is not designed to handle file uploads. API gateway converts binary data to base64 encoded text. Handling binary data as text consumes a lot of memory and processing gets tricky as well.
Also API gateway has a 10MB limit on payload size. The best approach to upload files is using S3. Even better approach would be to use a lambda function to generate a pre-signed S3 url to upload files.
Spring cloud function when integrated with an API gateway is intended to expose a single HTTP endpoint. However AWS Lambda spring boot integration by awslabs can expose multiple end points. Choose the approach that best works you.
Hope that helps.

Related

GET and POST Spring boot rest api with aws Lambda

I have a spring boot application with GET and POST request which is working fine. Now I want to use aws lambda. I have check various article and github project for converting serverless application but didn't find any useful.
I tried with simple application which accept string as input and it is running in aws lambda but my requirement is having json input for multiple POST requests.
If anyone can help me with how to test and run multiple POST request.

Amazon API Gateway and Spring cloud gateway use case

I am working on a distributed application project where there is need for rate limiting and authentication depending on the client consuming the service on an api gateway. I am wondering the best solution for designing the gateway.
Should I go with Spring cloud gateway or Spring Cloud function/AWS Lambda to create the gateway service?
I'd argue that using AWS API Gateway will make your life easier...
The benefits of using AWS API Gateway are:
it will remove all the operational cost of maintaining, configuring, monitoring and operating a Spring Cloud Gateway instance,
it will be highly available, with failover,
it will give you instant features like rate limiting, api keys, caching, authorization, canary testing, proxying, integration mapping, environments
it is very very cheap ($3.50 x MM requests).
The benefits of using Spring Cloud Function:
Define your API's as code within the application code itself
Leverage the ecosystem integration within Spring, for example, to run it locally on a dev's PC.
Cons of using API Gateway:
Deployment of new API's will be harder than using Spring Cloud Gateway (you need to configure each new resource/method)
Your costs are now tied to the number of requests... if you have a 900.000.000 millons/months API it could get expensive
Vendor lock-in
Cons of using Spring Cloud Function:
Operative cost of maintenance
Single point of failure
You can use Amazon API Gateway.
For more info on request throttling and quotas, please refer to the docs:
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html
I will rather use Istio gateway Envoy proxy rather than both options if permitted. Keeping my operational and maintenance cost little and no code change.

Filter Chains support in Spring Cloud Function

Does Spring Cloud Function provide some kind of functionality similar to Spring Security Filter Chains ?
One particular use case is to implement CORS with AWS Lambda API Gateway in proxy integration mode. According to the AWS docs, it's function responsibility to add CORS headers to the response.
It might be more useful to do this at the integration layer and not in the business logic.
I'm using Spring Cloud Function with AWS adapter and Spring Boot.
I've browsed through the code (3.1.3 at the time of writing) but didn't find something alike.
There's one old issue showing CorsFilter registration (with Azure provider) but I doubt it really worked as Spring Cloud Function does not utilize Servlet environment.

It is correct to use spring boot with amazon lambda?

I would like a solution that allows to manage json objects, calls to SOAP services and access to the DB via Spring data on a set of lambda services.
But on the net I read that lambda functions should be very simple.
Maybe Spring cloud is the solution?
Regards
In my opinion Spring Boot isn't a good technology choice for AWS Lambda but it's possible. The best way to start using it is to checkout the different wrappers and helpers in aws-serverless-java-container. There is also a good blog post about Spring Cloud Functions on AWS Lambda if that's interesting to you.
The internet tells you that Lambda functions should be simple because then they're easier to scale. If you create another monolith using Spring Boot on top of AWS Lambda, then this is not what AWS Lambda should be used for.
Below I'm listing advantages and disadvantages of using Spring Boot in AWS Lambda. There are probably more but these are the first ones that came to my mind.
Advantages
You can setup an API Gateway with proxy integration to AWS Lambda and then handle all the REST endpoints like you're used to with Spring Boot.
You don't have to manage your instances because AWS Lambda is doing that for you.
As soon as one Lambda function instance has started a Spring Boot container, this function will respond in a consistent way in terms of performance as expected from Java (at least that's my experience with Java Lambda functions).
Disadvantages
More complexity because you need to map an API Gateway event to an HTTP event that Spring Boot can handle. That's what the wrappers mentioned above already do for you.
A longer cold start time for your Lambda functions because Spring Boot is too slow to startup quickly like it's expected from Lambda functions. This means, you'll have spikes in your response times when a new Lambda function instance is started. If this is unacceptable, then don't choose Spring Boot with AWS Lambda.
You'll have multiple Spring Boot containers running without much control because AWS Lambda spins up instances if they are needed. You can control the max and min number of instances, but that's it.
Making SQL queries from AWS Lambda can be a pain due to the uncontrollable number of instances. You might run out of connections quite quickly if a spike hits your Lambda functions because it spins up more and more instances.
Having said that, I have used Java Lambda functions in the past and it is great to run them in the background doing some data processing. However, I'm not convinced that they are a good choice for "customer facing" endpoints like a REST API (except if you keep a minimum of Lambda instances running but then you can question if AWS Lambda is the right choice for you).

Spring Cloud Function-suitable for REST API? How to access GET path params?

I'm new to WebFlux and Serverless. I'm trying to create a REST API as Serverless via AWS API gateway.
The flow would be API Gateway --> Lambda --> DynamoDB
In order to achieve the API flow, would the Spring Cloud Function be the best choice? I found aws-serverless-java-container does the job seamlessly(wrapper of converting the event to http request/response)
I've gone through the documentation on http://cloud.spring.io/spring-cloud-function/single/spring-cloud-function.html and few examples found in https://github.com/spring-cloud/spring-cloud-function.
But still, I'm not convinced on whether with Spring Cloud Function I would be able to achieve the API flavor.
#Bean
//How path or query params can be mapped?
public Function<Flux<String>, Flux<String>> getEmployeeDetails() {
// business logic goes here
}
In the above snippet, how to achieve the GET request/response model. If my endpoint has /{dept}/{employee}/{name}, how Spring cloud function accepts the path params in GET request?
Any pointers would be helpful.
API Gateway wraps all data of the incoming request into an APIGatewayProxyRequestEvent object, which has several attributes, like the request body, path and query parameters, or the HTTP method of the original request.
For your use case, you would get the three path parameters dept, employee, and name.
However, the problem is that SpringBootApiGatewayRequestHandler, which does the mapping between the incoming APIGatewayProxyRequestEvent and your function, currently only considers a request body, but no other parameters at all.
I hope that the developers will fix this in the future.
In the meantime, you could implement a modified version of SpringBootApiGatewayRequestHandler, which considers the required parameters.
I've written a small article, which covers exactly this topic.
I have the same mistake with this, the documentation prompts you to think that you can do this, but you can't. This is only an example from spring-cloud-function, and springboot function aws specific code doesn't have this feature implemented (as far I could see).
You can follow the default route, if you want to implement your application in lambda with spring: https://github.com/awslabs/aws-serverless-java-container/blob/master/samples/springboot/pet-store.
Or... If you want, you can try the hard way, but attemption: you are completely alone: https://github.com/arawn/building-serverless-application-with-spring-webflux.
This project himself implements ObjecMapper conversions and you can get the parameters from request: https://github.com/arawn/building-serverless-application-with-spring-webflux/blob/master/src/main/java/serverless/aws/springframework/http/server/reactive/SimpleAPIGatewayProxyServerHttpRequest.java
The trick from here is to create Path template in lambda with proxy (Path: '/{proxy+}') and request are delegated from aws mapper.
Good luck!

Resources