When using doing rest we are not limited to calling a single API from our API server, at the end they could have multiple API servers and each can expose a different set of endpoints and each could be deployed in a different location, thus Domino-rest provides enough tools and mechanisms to deal with such scenarios without scattering the root or base urls of those API server all over the source code as listed below
When service root it not defined Domino-rest will assume that the service root is the same base url (Host and Port) from where it is being used.
Then if the application is deployed at localhost:8080 then all calls made by domino-rest clients will use localhost:8080 as the base or root service url, and service as a root path, for example :
DominoRestConfig.getInstance()
.setDefaultResourceRootPath("endpoint");
We can define a service root that is different from were the application is deployed and then all requests will be made to that base or root url, the configuration is available using the DominoRestConfig class
DominoRestConfig
.getInstance()
.setDefaultServiceRoot("http://127.0.0.1:9090/");
If we defined a global service root we override the default one for all request so our request for the above example will become :
http://127.0.0.1:9090/{path to service}
When we annotate a service using @ServiceFactory we can also specify the service root for that specific service or resource, the service root defined in this way will take priority over the default or the global service root, for example :
@RequestFactory(serviceRoot = "http://localhost:7070/library/")
public interface MoviesService {
@Path("movies/:movieName")
@GET
Movie getMovieByName(@PathParam("movieName") String movieName);
@Path("movies")
@GET
List<Movie> listMovies();
@Path("movies/:name")
@PUT
void updateMovie(@BeanParam @RequestBody Movie movie);
}
So now even if we define a global service root as stated above making calls using the client generated from this service will always make the request to http://localhost:7070/library/{path to service} instead of using the global one.
Instead of fixed service mapping for each service, or using one global service mapping for all service domino-rest allows mapping each service to a different root based on some matching conditions. for example we want all services that has a path starts with movies to map to http://localhost:7070/library/ while all services with paths starts with books map to http://localhost:9090 and so on. this is could also be very useful when the service roots are not fixed and could be defined as system properties or coming from some sort of configuration.
We can use the DominoRestConfig class to define our routing rules, for example :
DominoRestConfig.getInstance()
.addDynamicServiceRoot(DynamicServiceRoot
.pathMatcher(path -> path.startsWith("movies"))
.serviceRoot(() -> "http://localhost:7070/library/")
)
.addDynamicServiceRoot(DynamicServiceRoot
.pathMatcher(path -> path.startsWith("books"))
.serviceRoot(() -> "http://localhost:9090")
);
With this configuration when we have a service that does not match any of the specified rules it will fall back to use the global or default service root.
And such configuration will also help us remove the hard coded host and port from our services/resources definitions, for example we can rewrite the following resource :
@RequestFactory(serviceRoot = "http://localhost:7070/")
public interface MoviesService {
@Path("library/movies/:movieName")
@GET
Movie getMovieByName(@PathParam("movieName") String movieName);
@Path("library/movies")
@GET
List<Movie> listMovies();
@Path("library/movies/:name")
@PUT
void updateMovie(@BeanParam @RequestBody Movie movie);
}
To be like this :
@RequestFactory
@Path("library/")
public interface MoviesService {
@Path("movies/:movieName")
@GET
Movie getMovieByName(@PathParam("movieName") String movieName);
@Path("movies")
@GET
List<Movie> listMovies();
@Path("movies/:name")
@PUT
void updateMovie(@BeanParam @RequestBody Movie movie);
}
Then define a dynamic routing as the following :
DominoRestConfig.getInstance()
.addDynamicServiceRoot(DynamicServiceRoot
.pathMatcher(path -> path.startsWith("library"))
.serviceRoot(() -> "http://localhost:7070/library/")
)
With this we removed the hard coded host and port from the service definition but our methods still maps to the correct API server, for example the getMovieByName method will now map to http://localhost:7070/library/movies/{movie name}