From db2e84ef06efd8ca21b6d2dbd5f7e795b0c4821e Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Fri, 20 Mar 2020 19:58:47 +0100 Subject: [PATCH] Add test for passing `@MatrixVariable` without specified name. Add documentation for `@MatrixVariable` support. Fixes gh-307. --- .../main/asciidoc/spring-cloud-openfeign.adoc | 31 +++++++++++++++++++ .../support/SpringMvcContractTests.java | 19 ++++++++++++ 2 files changed, 50 insertions(+) diff --git a/docs/src/main/asciidoc/spring-cloud-openfeign.adoc b/docs/src/main/asciidoc/spring-cloud-openfeign.adoc index 76ffcd11..0bc222e3 100644 --- a/docs/src/main/asciidoc/spring-cloud-openfeign.adoc +++ b/docs/src/main/asciidoc/spring-cloud-openfeign.adoc @@ -524,6 +524,37 @@ public interface DemoTemplate { } ---- +=== Spring MatrixVariable Support + +Spring Cloud OpenFeign provides support for the Spring `@MatrixVariable` annotation. + +If a map is passed as the method argument, the `@MatrixVariable` path segment is created by joining key-value pairs from the map with a `=`. + +If a different object is passed, either the `name` provided in the `@MatrixVariable` annotation (if defined) or the annotated variable name is +joined with the provided method argument using `=`. + +IMPORTANT:: Even though, on the server side, Spring does not require the users to name the path segment placeholder same as the matrix variable name, since it would be too ambiguous on the client side, Sprig Cloud OpenFeign requires that you add a path segment placeholder with a name matching either the `name` provided in the `@MatrixVariable` annotation (if defined) or the annotated variable name. + +For example: + +[source,java,indent=0] +---- +@GetMapping("/objects/links/{matrixVars}") +Map> getObjects(@MatrixVariable Map> matrixVars); +---- +Note that both variable name and the path segment placeholder are called `matrixVars`. + +[source,java,indent=0] +---- +@FeignClient("demo") +public interface DemoTemplate { + + @GetMapping(path = "/stores") + CollectionModel getStores(); +} +---- + + === Troubleshooting ==== Early Initialization Errors diff --git a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/support/SpringMvcContractTests.java b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/support/SpringMvcContractTests.java index 997a3e8f..8daf7a8c 100644 --- a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/support/SpringMvcContractTests.java +++ b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/support/SpringMvcContractTests.java @@ -554,6 +554,22 @@ public class SpringMvcContractTests { .isEqualTo(data.indexToExpander().get(0).expand("value")); } + @Test + public void testMatrixVariableWithNoName() throws NoSuchMethodException { + Method method = TestTemplate_MatrixVariable.class + .getDeclaredMethod("matrixVariableNotNamed", Map.class); + MethodMetadata data = this.contract + .parseAndValidateMetadata(method.getDeclaringClass(), method); + Map testMap = new HashMap<>(); + + testMap.put("param", "value"); + + assertThat(data.template().method()).isEqualTo("GET"); + assertThat(data.template().url()).isEqualTo("/matrixVariable/{params}"); + assertThat(";param=value") + .isEqualTo(data.indexToExpander().get(0).expand(testMap)); + } + @Test public void testAddingTemplatedParameterWithTheSameKey() throws NoSuchMethodException { @@ -697,6 +713,9 @@ public class SpringMvcContractTests { @RequestMapping(path = "/matrixVariableObject/{param}") String matrixVariableObject(@MatrixVariable("param") Object object); + @RequestMapping(path = "/matrixVariable/{params}") + String matrixVariableNotNamed(@MatrixVariable Map params); + } @JsonAutoDetect