2
votes

I'm trying to setup a Spring Integration flow using the DSL style flows mixed with @Bean definitions. In this example, I'm attempting to mediate an incoming REST request (restCustomerGateway) as an inbound webflux gateway. I saw that you can use .payloadExpression to pull things out of the request (in this case the id path parameter...would be intersted if there are better or more typesafe ways).

I then flow it into a webflex outbound gateway (restCustomerSource) to make a downstream call, which should then be funneled back to the inbound gateway as a response. Note, there will eventually be transformers in between to do payload transformation/etc.

Simple question is, how do I structure this so that I have access to the 'id' (the path parameter, currently hardcoded to '1' in the outbound gateway invocation)? I'm assuming this is part of the message payload that flows between the two, but how do I get a handle to it?

@Bean
public WebFluxInboundEndpoint restCustomerGateway() {
    return WebFlux.inboundGateway("/rest/customers/{id}")
        .requestMapping(m -> m.produces(MediaType.APPLICATION_JSON_VALUE)).payloadExpression("#pathVariables.id")
        .get();
}

@Bean
public WebFluxRequestExecutingMessageHandler restCustomerSource() {
    return WebFlux.outboundGateway("http://localhost:8080/customers/1").httpMethod(HttpMethod.GET)
        .expectedResponseType(Customer.class)
        .get();
}

@Bean
public IntegrationFlow restCustomerFlow(CustomerProcessor customerProcessor) {
    return IntegrationFlows
        .from(restCustomerGateway())
        .handle(restCustomerSource())
        .handle(customerProcessor)
        .get();
}
1

1 Answers

2
votes

There is a

/**
 * Specify a {@link Function} to evaluate in order to generate the Message payload.
 * @param payloadFunction The payload {@link Function}.
 * @param <P> the expected HTTP request body type.
 * @return the spec
 * @see HttpRequestHandlingEndpointSupport#setPayloadExpression(Expression)
 */
public <P> S payloadFunction(Function<HttpEntity<P>, ?> payloadFunction) {

on the WebFluxInboundEndpointSpec, but you don't have there an access to the evaluation context variables or even to the original ServerWebExchange, only the RequestEntity is available in the function.

Since you stored that id path variable into the payload of the message to push downstream via payloadExpression("#pathVariables.id"), it is indeed available in the WebFlux.outboundGateway() for access.

You have there right now hard-coded uri, but you can use this variant instead:

/**
 * Create an {@link WebFluxMessageHandlerSpec} builder for request-reply gateway
 * based on provided {@code Function} to evaluate target {@code uri} against request message.
 * @param uriFunction the {@code Function} to evaluate {@code uri} at runtime.
 * @param <P> the expected payload type.
 * @return the WebFluxMessageHandlerSpec instance
 */
public static <P> WebFluxMessageHandlerSpec outboundGateway(Function<Message<P>, ?> uriFunction) {

So, therefore your config becomes like this:

WebFlux.outboundGateway(m -> "http://localhost:8080/customers/" + m.getPayload())