jakartaee / rest

Jakarta RESTful Web Services
Other
353 stars 114 forks source link

API for parsing URIs using templates #1112

Open mkarg opened 2 years ago

mkarg commented 2 years ago

Since its inception the JAX-RS API used templates in the UriBuilder and the @Path annotation. Time has proven that URI templates are very convenient. Unfortunately there are some use cases of templates uncovered by the Jakarta REST API. I'd like to propose to extend the API to support these use case, too:

While this can get performed with the help of regular expressions or the URI class, it not only would be much more convenient to have support for named template parameters instead, but it would also be cleaner to read and less prone to failures (like wrong index of segment).

As there could by several different solutions, I'd like to start a public discussion here, to see which ideas to follow and which to drop. My final target is to publish a PR for inclusion in v4.

Possible extension points to be discussed (among others):

Please discuss! :-)

mkarg commented 2 years ago

@jansupol @andymc12 @chkal @jelemux I would like to hear some initial opinion of you on this proposal, so I know whether it makes sense for me to turn it into a PR. Thanks.

chkal commented 2 years ago

I basically like the idea. IMO creating something like a UriTemplate class representing a template and providing methods to match a concrete URI against the template to extract the named parameters would be a first step.

jansupol commented 2 years ago

Sounds useful, but a couple of comments:

Extend the existing UriBuilder, UriInfo, and Link classes with new methods to parse against a template and retrieve single values of named parameters.

Not UriInfo, it is applicable on the server-side only.

Add a new facility to obtain the effective absolute template used by a specific resource method, considering all @Path annotations.

This sounds difficult on the client side.

Extend existing RuntimeDelegate to produce instance of UriTemplate (or UriParser) and to resolve the task of building the full template for a given resource method.

There was the idea to drop RuntimeDelegate in 4.0. Have we dropped the idea to drop it?

jelemux commented 1 year ago

Looks like a good idea to me. As for the solution, from what @jansupol wrote, I'm guessing option 2 would be our best option. I imagine it somewhat like this:

public abstract class UriTemplate {

    protected final String templateString;

    protected UriTemplate(String templateString) {
        this.templateString = templateString;
    }

    public abstract Map<String,String> parseParams(URI toParse) throws UriTemplateException;

    public abstract String parseParam(URI toParse, String name) throws UriTemplateException;

    public abstract <T> T parseParamWithType(URI toParse, String name, Class<T> paramClass) throws UriTemplateException;

    public abstract boolean matches(URI toMatch);

    public abstract static class UriTemplateException extends Exception {
        // ...
    } // maybe add some subclasses like UriTemplateNotMatchingException, UriTemplateInvalidTypeException or something along those lines

}

Exclaimer: This is just a crude prototype and maybe not what we want at all. Just my thoughts on the matter.