I'm working on a big project with many modules, where every API endpoint is regrouped as separated modules and described in interfaces.
For the moment we're using a Jersey WebResourceFactory which enable us to create a client-side representation of our endpoints that are shared in other modules willing to call those services. Using the client-side representation as it is for the moment makes the calls to the services transparent for the different clients and by that I mean that we don't have to hardcode urls to the outer services or methods of it.
I'm wondering if there is a similar mechanism in SpringBoot directly, that would enable me to create such a client-side representation of the services.
To make it simple: I would like to proxify the services, defined through separate interfaces, as that I barely never have to encode in the clients the real path ( "..../books/{id}") to a service myself.
(This is indeed only possible in clients using the spring context, like other spring services or Applications. It is indeed impossible to use it in frontends for eg.)
Edit: Adding some code as examples beneath.
Jersey (actual) example:
One interface:
@Path("/release")
public interface ReleaseServiceResource {
@POST
@Path("/start")
boolean start();
@GET
@Path("/isactive")
boolean isBusy();
}
ServerConfiguration class ( which also creates the proxies of the interfaces) :
@Configuration
public class ServerConfiguration {
@Inject
private RestUriProvider uriProvider;
@Bean
public ReleaseServiceResource releaseServiceResource() {
return proxy(ReleaseServiceResource.class,uriProvider.createBaseRestUri());
}
public <T> T proxy(Class<T> proxyInterface, URI uri) {
ClientConfig config = new ClientConfig().property(CONNECTION_MANAGER, new PoolingHttpClientConnectionManager())
...
return newResource(proxyInterface, JerseyCLient.createClient(config).target(uri));
}}
RestUriBean:
@Named
public class RestUriProvider {
public Uri createBaseRestUri() {
return UriBuilder.path(“http://server_ip:port/my_service”).build();
}
}
Usage of the service which is quiet transparent for the client in the DefaultReleaseService:
@Named
public class DefaultReleaseService {
@Inject
private ReleaseServiceResource releaseServiceResource;
public boolean triggerRelease() {
return releaseServiceResource.start();
}
}
With SpringBoot the classes would be something like:
One interface:
@RestController
@RequestMapping("/release")
public interface ReleaseServiceResource {
@PostMapping("/start")
boolean start();
@GetMapping("/isactive")
boolean isBusy();
}
Usage of the service
@Named
public class DefaultReleaseService {
@Inject
private RestTemplate template;
@Inject
private RestUrlProvider urlProvider;
public boolean triggerRelease() {
return template.exchange(urlProvider.createBaseRestUrl() + “/release/start”, POST, Boolean.class).getBody();
}
}
Rest URI Provider:
@Named
public class RestUrlProvider {
public String createBaseRestUrl() {
return “http://server_ip:port/my_service”;
}
}