Is it desirable to create a first-class URI contract concept across
multiple components? I am not sure if this has been discussed before
so I think a short example might help to illustrate what I mean.
Assume the architecture is following a DRY principle with the goal of
separating the REST application into three distinct units: "Common",
"Server", and "Client". Only "Common" should need to know about the
internal URI contract requirements. I follow the conviction that an
API-proposal needs to fit on one piece of page. So let me contrast
JAX-RS' current design with a different approach by given a
code-snippet example. I hope with this post I can get constructive
feedback if this is a desirable design alternative from the one put
forth in JAX-RS.
Code Snippets:
== Contract/Commons ==
/**
* Define a URI contract that has the template {path}/{urn}.
* Example URL: "http://localhost:80/a/path/to/urn:some:document"
*/
@UriPattern("{path}/{urn}")
CoolResourceURI implements ResourceURI {
@Variable("path")
private final String path;
@Variable("urn", "urn:\\.*")
private final URI urn;
getPath() {
return path;
}
getURN() {
return urn;
}
...
}
== Server-Side ==
/**
* Attach [EMAIL PROTECTED] CoolResource} servlet to the [EMAIL PROTECTED]
CoolResourceURI} contract.
*/
@UriContract(CoolResourceURI.class)
class CoolResource {
/**
* Handle [EMAIL PROTECTED] GET} HTTP/1.1 request for resources that map to
{path}/{urn}
*/
get(CoolResourceURI uri) {
// do something with the URI components
// Ex: "/some/path/urn:cool:cow"
// --> path="/some/path", urn="urn:cool:cow"
...(uri.getPath(), uri.getURN());
}
...
}
== Client-Side ==
/*
* Send [EMAIL PROTECTED] GET} HTTP/1.1 request for an URI whose lexical
representation matches the template {path}/{urn}
*/
... = getRestController().get(new CoolResourceURI("/some/path",
"urn:cool:cow"));
Notice how this different design strategy would strengthen the
weakly-typed solution that we currently see in the JSR draft. I tried
to demonstrate an improvement to the API by showing three REST
components that use ResourceURIs (see "CoolResourceURI" as an example)
as a means to encapsulate the URI contract to which the REST service
must adhere.
Also note how the "CoolResource#get(CoolResourceURI)" method is a
type-strong and an succinct way of saying that only GET HTTP/1.1
requests for a specific URI contract should be fulfilled.
Regards,
Alex Horn