This section will try to sort out the best way to implement programmatic endpoint configuration. The approach taken is to make as few changes as possible to RestEasy, which is means that when changes were required whole methods have been copied and those new methods changed were possible.
The following branch contains the code discussed in this document: programmatic-config
Lets starting with a very basic POJO like this:
public class Pojo
{
public String doit()
{
return "Pojo done";
}
public String process(String msg)
{
return msg;
}
}
This class will simulate our the target endpoint and as you can see it has no annotations. Next, step is to figure out how we describe such a class and get RestEasy to be able to handle it.
Building a REST endpoint for the class above could be done in the following manner.
Start by:
ResourceClassConfig config = ResourceConfig.resourceClass(Pojo.class)
Next, using code completion suggestions you should see the following options:
In this case we don't require anything except the rootPath:
ResourceClassConfig config = ResourceConfig.resourceClass(Pojo.class)
.rootPath("/")
To configure the method doit in the Pojo.class we specify that we want to add a new resource method:
ResourceClassConfig classConfig = ResourceConfig.resourceClass(Pojo.class)
.rootPath("/")
.resourceMethod().
You should now see the code completion options available for configuring the method:
For this example we'll add the following:
ResourceClassConfig classConfig = ResourceConfig.resourceClass(Pojo.class)
.rootPath("/")
.resourceMethod()
.httpMethods(GET)
.path("some/path/doit")
.consumes("*/*")
.produces("*/*")
.name("doit").
And to add another method just continue to use the code completion after the returns method call.
The end result would then be:
ResourceClassConfig classConfig = ResourceConfig.resourceClass(Pojo.class)
.rootPath("/")
.resourceMethod()
.httpMethods(GET)
.path("some/path/doit")
.consumes("*/*")
.produces("*/*")
.name().
.returns(String.class)
.resourceMethod()
.httpMethods(GET)
.name("process")
.queryParam(String.class, "msg")
.returns(String.class)
.build();
The end result of this configuration should be the equivalent JAX-RS annotated class:
@Path ("/")
@Consumes ("*/*")
@Produces ("*/*")
public class Pojo
{
@GET
@PATH ("some/path/doit")
@Consumes ("*/*)
@Produces ("*/*")
public String doit()
{
return "Pojo done";
}
@GET
public String process(@QueryParam("msg") String msg)
{
return msg;
}
}
The full path to the method doit would be "/some/path/doit", and since we have not specified a path for the process method it's path with default to the name of the method, "/process".
Note The type specified in the returns method is currently ignored, and what is returned is whatever the target method returns. This is something that we are currently working on and we'll post back with a suggestion as soon as we have something to show.
We would be interested to hear what people think about this approach. Any feedback is most welcome.
Hi Daniel, IMHO it woud be very nice if your "programmatic-resource-configuration-feature" would come out of the box (pull request) or at least it would be obtainable via a MVN repository.