GH-864 Add support for carying HTTP request parameters in Message headers
Resolves #864
This commit is contained in:
@@ -650,6 +650,13 @@ When POSTing text the response format might be different with Spring Boot 2.0 an
|
|||||||
|
|
||||||
See <<Testing Functional Applications>> to see the details and example on how to test such application.
|
See <<Testing Functional Applications>> to see the details and example on how to test such application.
|
||||||
|
|
||||||
|
==== HTTP Request Parameters
|
||||||
|
As you have noticed from the previous table, you can pass an argument to a function as path variable (i.e., `/{function}/{item}`).
|
||||||
|
For example, `http://localhost:8080/uppercase/foo` will result in calling `uppercase` function with its input parameter being `foo`.
|
||||||
|
|
||||||
|
While this is the recommended approach and the one that fits most use cases cases, there are times when you have to deal with HTTP request parameters.
|
||||||
|
The framework will treat HTTP request parameters similar to the HTTP headers by storing them in `Message` headers under the header key `http_request_param`
|
||||||
|
with its value being a `Map` of request parameters, so in order to access them your function input signature should accept `Message` type (e.g., `Function<Message<String>, String>`). For convenience we provide `HeaderUtils.HTTP_REQUEST_PARAM` constant.
|
||||||
|
|
||||||
=== Function Mapping rules
|
=== Function Mapping rules
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,15 @@ public final class FunctionWebRequestProcessingHelper {
|
|||||||
|
|
||||||
HttpHeaders headers = wrapper.getHeaders();
|
HttpHeaders headers = wrapper.getHeaders();
|
||||||
|
|
||||||
Message<?> inputMessage = argument == null ? null : MessageBuilder.withPayload(argument).copyHeaders(headers.toSingleValueMap()).build();
|
Message<?> inputMessage = null;
|
||||||
|
|
||||||
|
if (argument != null) {
|
||||||
|
MessageBuilder builder = MessageBuilder.withPayload(argument);
|
||||||
|
if (!CollectionUtils.isEmpty(wrapper.getParams())) {
|
||||||
|
builder = builder.setHeader(HeaderUtils.HTTP_REQUEST_PARAM, wrapper.getParams().toSingleValueMap());
|
||||||
|
}
|
||||||
|
inputMessage = builder.copyHeaders(headers.toSingleValueMap()).build();
|
||||||
|
}
|
||||||
|
|
||||||
if (function.isRoutingFunction()) {
|
if (function.isRoutingFunction()) {
|
||||||
function.setSkipOutputConversion(true);
|
function.setSkipOutputConversion(true);
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ import org.springframework.messaging.MessageHeaders;
|
|||||||
*/
|
*/
|
||||||
public final class HeaderUtils {
|
public final class HeaderUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message Header name which contains HTTP request parameters.
|
||||||
|
*/
|
||||||
|
public static final String HTTP_REQUEST_PARAM = "http_request_param";
|
||||||
|
|
||||||
private static HttpHeaders IGNORED = new HttpHeaders();
|
private static HttpHeaders IGNORED = new HttpHeaders();
|
||||||
|
|
||||||
private static HttpHeaders REQUEST_ONLY = new HttpHeaders();
|
private static HttpHeaders REQUEST_ONLY = new HttpHeaders();
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
package org.springframework.cloud.function.web.mvc;
|
package org.springframework.cloud.function.web.mvc;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -29,10 +31,12 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
|||||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
import org.springframework.cloud.function.web.RestApplication;
|
import org.springframework.cloud.function.web.RestApplication;
|
||||||
import org.springframework.cloud.function.web.mvc.PrefixTests.TestConfiguration;
|
import org.springframework.cloud.function.web.mvc.PrefixTests.TestConfiguration;
|
||||||
|
import org.springframework.cloud.function.web.util.HeaderUtils;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.RequestEntity;
|
import org.springframework.http.RequestEntity;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.messaging.Message;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -65,6 +69,15 @@ public class PrefixTests {
|
|||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void uppercase() throws Exception {
|
||||||
|
ResponseEntity<String> result = this.rest.exchange(
|
||||||
|
RequestEntity.get(new URI("/functions/uppercase/foo?nome=Doe&prenome=John")).build(), String.class);
|
||||||
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
|
assertThat(result.getBody()).isEqualTo("[\"foo\",\"bar\"]");
|
||||||
|
}
|
||||||
|
|
||||||
@EnableAutoConfiguration
|
@EnableAutoConfiguration
|
||||||
@org.springframework.boot.test.context.TestConfiguration
|
@org.springframework.boot.test.context.TestConfiguration
|
||||||
protected static class TestConfiguration {
|
protected static class TestConfiguration {
|
||||||
@@ -74,6 +87,17 @@ public class PrefixTests {
|
|||||||
return () -> Flux.fromArray(new String[] { "foo", "bar" });
|
return () -> Flux.fromArray(new String[] { "foo", "bar" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Function<Message<String>, String[]> uppercase() {
|
||||||
|
return message -> {
|
||||||
|
assertThat(message.getPayload().equals("foo"));
|
||||||
|
Map<String, String> httpParam = (Map<String, String>) message.getHeaders().get(HeaderUtils.HTTP_REQUEST_PARAM);
|
||||||
|
assertThat(httpParam.get("nome")).isEqualTo("Doe");
|
||||||
|
assertThat(httpParam.get("prenome")).isEqualTo("John");
|
||||||
|
return new String[] { "foo", "bar" };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user