RestClientBuilder
-built clients
@Path
interface-level annotation on the interface, but I notice in the spec, the @Path
isn't included in the interface. Is the intent here that only the implementation would include a class-level @Path
and in order to point to the right place, you'd include that path value in your baseUri when constructing the client proxy?
Hi @jwcarman - I work on MP Rest Client and on Open Liberty - I'll reply here with "MP" hat on, and reply in the OL channel with my "OL" hat.
The MP Rest Client spec is really only interested in the client side - or rather providing a client side view of the remote service. Since it is intended to work with any REST service, not necessarily a JAX-RS-based service, we don't require or recommend the pattern of JAX-RS resource classes implementing an interface that can also be re-used as the Rest Client interface - though, I do believe that that is a fairly common pattern.
To ensure portability with this pattern, I think that we would need to change the JAX-RS (now Jakarta RESTful Web Services) spec to allow interface inheritance of annotations.
As you mentioned in the other thread, it is possible to put no annotations on the client interface and define the path using the baseUri when creating the client instance - for example:
@Path("path")
public interface MyClient { //...
}
MyClient client = RestClientBuilder.newBuilder().baseUri("http://myhost:9080/app-path").build(MyClient.class);
is effectively the same as:
public interface MyClient { //...
}
MyClient client = RestClientBuilder.newBuilder().baseUri("http://myhost:9080/app-path/path").build(MyClient.class);
@Path
annotations surprising or confusing. I agree that the current situation makes life easier for application servers, but in this case I would love to see a less surprising behaviour. In fact, a few colleagues of mine tried to refactor our app and tapped into the same pitfall. But defining a good inheritance strategy for conflicting annotations should be possible. Also, JAX-RS endpoints do not need to be CDI beans as far as I know, do they?
I'd call not inheriting the @Path annotations surprising or confusing. I agree that the current situation makes life easier for application servers, but in this case I would love to see a less surprising behaviour. In fact, a few colleagues of mine tried to refactor our app and tapped into the same pitfall. But defining a good inheritance strategy for conflicting annotations should be possible.
No arguments from me, but this is an issue to be taken up with the JAX-RS community. It is possible that this is something that could be put into the 3.1 release - the 3.0 release is basically just changing the package names.
Also, JAX-RS endpoints do not need to be CDI beans as far as I know, do they?
Today, no. The JAX-RS spec is written in such a way that says if CDI is present, then JAX-RS resources and providers will be managed by CDI. But if CDI is not present, then the JAX-RS runtime manages the lifecycle/injection of the resources/providers.
In future JAX-RS spec releases, CDI will be required and will be replacing JAX-RS's mechanism of context injection and lifecycle management.
that's good feedback - you might want to add that to:
eclipse-ee4j/jaxrs-api#569
I like this statement :-)
JAX-RS in Spring Boot (love the glue, hate WebMVC).
InvocationContext#getMethod
returns an interface method, while the "normal" cdi interceptor mechanism returns my "implementation" class there
InvocationContext#getMethod
. You could verify the funtionality by just checking the method name or its signature or simply by putting a boolean into the interceptor and flipping it to true once it gets invoked, then asserting on it. Either of these assertions would IMO fulfill the test purpose in full while being more relaxed towards how the feature is implemented.
m.getDeclaringClass() instanceof ClientWithURIAndInterceptor
to ensure that it's invoking the right interface?
Does microprofile-rest-client supports like this:
//The original interface
public interface MyService {
MyDTO get(String id);
}
//The rest client
@Path("/my_service")
@RegisterRestClient(configKey = "my_service")
@RegisterClientHeaders
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public interface MyServiceRestClient extends MyService{
@Override
@Path("/get/{id}")
@GET
MyDTO get(String id);
}
//The usage
@ApplicationScope
public class MyAnotherService {
@Inject
@RestClient
MyService myService;
public void doSmothing(){
MyDTO md = myService.get("the id");
//......
}
}
MyService
.