Skip to content

Commit 2dbe24a

Browse files
Daniil Kudryavtsevvelo
authored andcommitted
Add composed Spring annotations support (OpenFeign#1090)
* Add composed Spring annotations support
1 parent ba9d3c8 commit 2dbe24a

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

spring4/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ The ```consume``` adds the first value as the `Content-Type` header.
1818
#### `@RequestMapping`
1919
Appends the value to `Target.url()`. Can have tokens corresponding to `@PathVariable` annotations.
2020
The method sets the request method.
21+
#### `@GetMapping`
22+
Appends the value to `Target.url()`. Can have tokens corresponding to `@PathVariable` annotations.
23+
Sets the `GET` request method.
24+
#### `@PostMapping`
25+
Appends the value to `Target.url()`. Can have tokens corresponding to `@PathVariable` annotations.
26+
Sets the `POST` request method.
27+
#### `@PutMapping`
28+
Appends the value to `Target.url()`. Can have tokens corresponding to `@PathVariable` annotations.
29+
Sets the `PUT` request method.
30+
#### `@DeleteMapping`
31+
Appends the value to `Target.url()`. Can have tokens corresponding to `@PathVariable` annotations.
32+
Sets the `DELETE` request method.
33+
#### `@PatchMapping`
34+
Appends the value to `Target.url()`. Can have tokens corresponding to `@PathVariable` annotations.
35+
Sets the `PATCH` request method.
2136
### Parameter Annotations
2237
#### `@PathVariable`
2338
Links the value of the corresponding parameter to a template variable declared in the path.

spring4/src/main/java/feign/spring/SpringContract.java

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,12 @@
1313
*/
1414
package feign.spring;
1515

16-
import java.lang.annotation.Annotation;
17-
import java.lang.reflect.Method;
1816
import java.util.ArrayList;
1917
import java.util.Collection;
20-
import org.springframework.web.bind.annotation.ExceptionHandler;
21-
import org.springframework.web.bind.annotation.PathVariable;
22-
import org.springframework.web.bind.annotation.RequestBody;
23-
import org.springframework.web.bind.annotation.RequestMapping;
24-
import org.springframework.web.bind.annotation.RequestParam;
25-
import org.springframework.web.bind.annotation.ResponseBody;
26-
import feign.Contract.BaseContract;
18+
import org.springframework.web.bind.annotation.*;
2719
import feign.DeclarativeContract;
2820
import feign.MethodMetadata;
21+
import feign.Request;
2922

3023
public class SpringContract extends DeclarativeContract {
3124

@@ -51,6 +44,42 @@ public SpringContract() {
5144
data.template().method(requestMapping.method()[0].name());
5245
});
5346

47+
48+
registerMethodAnnotation(GetMapping.class, (mapping, data) -> {
49+
appendMappings(data, mapping.value());
50+
data.template().method(Request.HttpMethod.GET);
51+
handleProducesAnnotation(data, mapping.produces());
52+
handleConsumesAnnotation(data, mapping.consumes());
53+
});
54+
55+
registerMethodAnnotation(PostMapping.class, (mapping, data) -> {
56+
appendMappings(data, mapping.value());
57+
data.template().method(Request.HttpMethod.POST);
58+
handleProducesAnnotation(data, mapping.produces());
59+
handleConsumesAnnotation(data, mapping.consumes());
60+
});
61+
62+
registerMethodAnnotation(PutMapping.class, (mapping, data) -> {
63+
appendMappings(data, mapping.value());
64+
data.template().method(Request.HttpMethod.PUT);
65+
handleProducesAnnotation(data, mapping.produces());
66+
handleConsumesAnnotation(data, mapping.consumes());
67+
});
68+
69+
registerMethodAnnotation(DeleteMapping.class, (mapping, data) -> {
70+
appendMappings(data, mapping.value());
71+
data.template().method(Request.HttpMethod.DELETE);
72+
handleProducesAnnotation(data, mapping.produces());
73+
handleConsumesAnnotation(data, mapping.consumes());
74+
});
75+
76+
registerMethodAnnotation(PatchMapping.class, (mapping, data) -> {
77+
appendMappings(data, mapping.value());
78+
data.template().method(Request.HttpMethod.PATCH);
79+
handleProducesAnnotation(data, mapping.produces());
80+
handleConsumesAnnotation(data, mapping.consumes());
81+
});
82+
5483
registerMethodAnnotation(ResponseBody.class, (body, data) -> {
5584
handleConsumesAnnotation(data, "application/json");
5685
});

spring4/src/test/java/feign/spring/SpringContractTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public class SpringContractTest {
4747
public void setup() throws IOException {
4848
mockClient = new MockClient()
4949
.noContent(HttpMethod.GET, "/health")
50+
.noContent(HttpMethod.GET, "/health/1")
5051
.noContent(HttpMethod.GET, "/health/1?deep=true")
5152
.noContent(HttpMethod.GET, "/health/1?deep=true&dryRun=true")
5253
.ok(HttpMethod.GET, "/health/generic", "{}");
@@ -83,6 +84,13 @@ public void inheritance() {
8384
Arrays.asList("application/json")));
8485
}
8586

87+
@Test
88+
public void composedAnnotation() {
89+
resource.check("1");
90+
91+
mockClient.verifyOne(HttpMethod.GET, "/health/1");
92+
}
93+
8694
@Test
8795
public void notAHttpMethod() {
8896
thrown.expectMessage("is not a method handled by feign");
@@ -115,6 +123,9 @@ public void check(
115123
@RequestParam(value = "deep", defaultValue = "false") boolean deepCheck,
116124
@RequestParam(value = "dryRun", defaultValue = "false") boolean dryRun);
117125

126+
@GetMapping(value = "/{id}")
127+
public void check(@PathVariable("id") String campaignId);
128+
118129
@ResponseStatus(value = HttpStatus.NOT_FOUND,
119130
reason = "This customer is not found in the system")
120131
@ExceptionHandler(MissingResourceException.class)

0 commit comments

Comments
 (0)