Let's suppose we want to implement the typical use case for JAX-RS developers: for a given REST service, define:
- interface
- server-side implementation
- proxy client
With introduction of Declarative HTTP Interface, this can now be accomplished with:
interface
@HttpExchange("/rest/users")
@RequestMapping("/rest/users")
public interface UserService {
@GetExchange(value = "/")
@GetMapping(value = "/")
List<User> search();
}
controller
@RestController
public class UserServiceImpl implements UserService {
public List<User> search() {
return List.of();
}
}
client
WebClient client = WebClient.builder().baseUrl(baseUrl).build();
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build();
UserService userService = factory.createClient(UserService.class);
userService.seatch();
The trouble
So far, so good: all works.
The point is: is it really necessary to double each annotation on the interface, one time for the controller, one time for the client? Both annotations are providing the same information.
Comment From: quaff
It confuse me too.
Comment From: bclozel
The sample you've shown indeed begs the question - why not share the server annotations for the interface client generation? @RequestMapping
method signatures can be very flexible and in many cases, they can depend on server types or worse, are not precise enough to generate an actual HTTP request.
Spring Cloud OpenFeign has tested this approach and is moving away from it on purpose. See spring-cloud/spring-cloud-openfeign#678. This also has been discussed in more details in this talk: https://youtu.be/5LNOnVJKW_4?t=1156
Comment From: ilgrosso
Thank you for explanation and further details @bclozel
Comment From: quaff
Could spring provider built-in annotations that combine server and client annotations. like this
@GetMapping
@GetExchange
public @interface Get {
@AliasFor(annotation = {GetMapping.class, GetExchange.class})
String[] value() default {};
}
Comment From: bclozel
@quaff unfortunately, this wouldn't solve the problems listed in the issues/talk I've pointed to.
Comment From: quaff
@quaff unfortunately, this wouldn't solve the problems listed in the issues/talk I've pointed to.
I understand that, but it will satisfy some scenes that people doesn't face those issues.
Comment From: DanielLiu1123
Hi @quaff, I think httpexchange-spring-boot-starter may resolve the problem.
It adds additional support for Spring web annotations, e.g. @RequestMapping
, @GetMapping
etc.
Comment From: quaff
Hi @quaff, I think httpexchange-spring-boot-starter may resolve the problem.
It adds additional support for Spring web annotations, e.g.
@RequestMapping
,@GetMapping
etc.
Thanks for your recommendation, I hope it could be fixed at framework side.