Issue
I've created an AWS Lambda based Spring Cloud Function with multiple functions and it works fine when I define exactly one "spring_cloud_function_definition" environment variable in the AWS Lambda Configuration panel. These functions' input and output is a Message<?>, so the payload and http headers can be accessed runtime as well.
I'd like to use this AWS Lambda function in different API Gateway methods, so for example:
- /item [POST] -> saveItem should be called
- /item [DELETE] -> deleteItem should be called
- ... and so on...
I found this documentation on Spring.io which says it's feasible:
If the input argument is of type Message<?>, you can communicate routing instruction by setting one of spring.cloud.function.definition or spring.cloud.function.routing-expression Message headers. For more static cases you can use spring.cloud.function.definition header which allows you to provide the name of a single function (e.g., …definition=foo) or a composition instruction (e.g., …definition=foo|bar|baz)
So the following test event should run in AWS Lambda without any failure:
{ "method": "POST", "body": "{ "key" : "value" }", "headers": { "spring.cloud.function.definition": "saveItem" } }
but of course it throws an exception:
No function defined: java.lang.IllegalStateException
java.lang.IllegalStateException: No function defined
at org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer.apply(AbstractSpringFunctionAdapterInitializer.java:187)
at org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler.handleRequest(SpringBootRequestHandler.java:51)
at org.springframework.cloud.function.adapter.aws.SpringBootApiGatewayRequestHandler.handleRequest(SpringBootApiGatewayRequestHandler.java:140)
at org.springframework.cloud.function.adapter.aws.SpringBootApiGatewayRequestHandler.handleRequest(SpringBootApiGatewayRequestHandler.java:43)
I've tried many configurations (application.properties, AWS Lambda env property, header, etc.) but nothing happened:
- spring.cloud.function.routing-expression=headers.function_name
- setting spring.cloud.function.definition=saveItem
What could be the problem? What is the best configuration in this case? Any help would be appreciated!
Used technologies:
- Cloud: AWS
- Cloud components: Lambda + API Gateway
- AWS Lambda handler class: org.springframework.cloud.function.adapter.aws.SpringBootApiGatewayRequestHandler
- AWS Lambda input and output events: APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent
- Java: 8
- Spring Cloud Function version: 3.0.6.RELEASE
Solution
I've updated to v3.1.3 and switched to FunctionInvoker and I've added the function definition to the request template mapping header, and it worked fine.
Anyways, thanks for the help. :)
Answered By - peter.szrnka
Answer Checked By - Candace Johnson (JavaFixing Volunteer)