[jsr356-experts] Dynamic Path matching

From: Danny Coward <danny.coward_at_oracle.com>
Date: Fri, 14 Sep 2012 16:43:28 -0700

Hi folks,

Wanted to get your input on a few ideas to do with more flexible path
matching. Currently in the API, the endpoint by default gets matched on
the URI for an opening handshake using an exact match with the URI used
to register it. And the developer can override this behavior with
whatever matching criteria they want to.

But for the developer using annotations, I wanted to explore the options
for something more flexible than just exact match on the path()
attribute of the class-level @WebSocketEndpoint annotation. It would
allow POJOs to map more flexibly in the URL space, could be useful for
developers (especially to javascript clients).

Here are a few directions to look at (some inspired by servlet and
JAX-RS schemes):-

0) Re-use the servlet concept of url-patterns

In this case, the path() attribute on the @WebSocketEndpoint annotations
would be able to contain servlet url-patters, matching defined as in the
servlet spec, for example:-

@WebSocketEndpoint(path="/club") - endpoint matches /club only
@WebSocketEndpoint(path="/club/*") - endpoint matches anything beginning
@WebSocketEndpoint(path="/club/*.websocket") - endpoint matches anything
ending .websocket

1) Allow method level annotations to define subpaths.

Here, the class level @WebSocketEndpoint defines a path, as it does now.
But, for example @WebSocketMessage could add a subpath in order to match
only on the aggregate path. For example,

public class Bar {

     public void takeOrder(String orderString, Session session) {
         // called from websocket clients who connected to
         // yeah, we'll get to you when we get to you

     public void takeExpressOrder(String orderString, Session session) {
         // called from websocket clients who connected to /club/vips
         // ice and lemon ?

2) Allow regular expressions in the URI paths

Here, the class level @WebSocketEndpoint annotation's path() variable
would be allowed to use regular expressions. The container would match
the opening handshake URI to the regular-expression URI. The developer
could ask for the actual URI path used to connect to be passed into
method parameters by annotating a String parameter with a new
@PathSegment annotation.

// means this POJO is an endpoint for all URLs that begin with club,
could substitute any regular expression instead.
public class Bar {

     public void doGreet(String orderString, Session session,
@PathSegment String partialPath) {
         // partialPath is the rest of the URI after "/club"
         // etc

3) Allow a kind of path templating, where path segments may be used in
web socket code.

Here, the kind of URIs allowed in the @WebSocketEndpoint path()
attribute could include variable path segments, where the variables can
be passed as parameters (annotated with a new @PathParam annotation)
into the methods on the POJO later.

// means this POJO is an endpoint for all URLs that begin with "/club"
public class Bar {
     public void takeOrder(String orderString,
@PathParam(id="member-level") String mLevel,
@PathParam(id="member-name") String mName, Session session) {
         if ("vip".equals(mLevel)) {
             // "Good evening, " + nName + " I have your drink already
         } else {
             // wait your turn mate

I think in general one, or some hybrid of two of these four approaches
would be a good addition to the model. The servlet one (0) may be well
understood, but doesn't seem as useful as 2) or 3). Clearly all four
would be overkill.

I'd be interested to know your thoughts on these approaches.

- Danny

<http://www.oracle.com> 	*Danny Coward *
Java EE
Oracle Corporation