BenniH
BenniH

Reputation: 11

Spring Cloud Function with Function Routing in AWS Lambda using API Gateway

I have tried to deploy a Spring Cloud Function with multiple functions in AWS Lambda.

For HTTP access I have created an HTTP API Gateway (not a REST API). I wanted to use function routing as described here: https://cloud.spring.io/spring-cloud-static/spring-cloud-function/3.0.1.RELEASE/reference/html/spring-cloud-function.html#_function_routing.

With the following configuration, the RoutingFunction shoud deleagte the call to the correct function based on the function HTTP-Header:

spring.cloud.function.routing-expression=headers.function

The Lambda Handler class is:

org.springframework.cloud.function.adapter.aws.SpringBootApiGatewayRequestHandler

and the configured function name (FUNCTION_NAME) is: functionRouter.

When I send a Request to the API-Gateway, the FunctionRouter gets a FluxJust object instead of a Message object, because the RequestHandler seems to be a Publisher. So I get the following exception:

EL1008E: Property or field 'headers' cannot be found on object of type
'reactor.core.publisher.FluxJust' - maybe not public or not valid?:
org.springframework.expression.spel.SpelEvaluationException

org.springframework.expression.spel.SpelEvaluationException:
EL1008E: Property or field 'headers' cannot be found on object of type
'reactor.core.publisher.FluxJust' - maybe not public or not valid?

My current workaround is to intercept the request before the request is delegated to the RoutingFunction and try to reconstruct the payload from the HashMap with the following code:

@Autowired
RoutingFunction f;

@Bean
public Function<Message<LinkedHashMap>,?> router() {
    return value -> {
        String json = new JSONObject(value.getPayload()).toString();
        Message<?> m = MessageBuilder.createMessage(json, value.getHeaders());
        Object result = f.apply(m);
        return result;
    };
}

Is there a way proper way to use the HTTP API Gateway in combination with Function Routing in AWS?

Upvotes: 1

Views: 2533

Answers (1)

mapuo
mapuo

Reputation: 1

On my project I've set function.definition and function.routing-expression like that:

spring.cloud.function.definition=functionRouter
spring.cloud.function.routing-expression=headers['pathParameters']['proxy']

This will be using the org.springframework.cloud.function.context.config.RoutingFunction that Spring Cloud Function provides and the expression would get the function name from the path.

If you still want to use the headers you could do: spring.cloud.function.routing-expression=headers['headers']['function']. The HTTP headers are added in the Message headers in the headers property. So first we get the Message headers and then the HTTP headers and then the header key.

Upvotes: 0

Related Questions