RESTFaces
Ryan J. McDonough has written a post called "Not much is RESTful in RestFaces and JBoss Seam", which discusses the RESTfaces JSF extension. On RESTfaces he concludes:
"I just came across a quick article on The Server Side about a JSF framework called RESTFaces. My initial reaction was 'oh cool, a JSF framework that might adhere to RESTful principals.' Sadly, there isn’t very much that is “RESTful” about RESTFaces."
Unfortunately, I have to agree. REST is becoming something of a buzzword these days and I suspect RESTfaces might be suffering from that instead of focusing on what it actually does, which is provided a patch for JSF to allow CGI style links. Looking at the documentation, it says:
" RESTfaces for JavaServer™ Faces Technology make it possible to write bookmarkable pages using JavaServer™ Faces."
And that's true, it does, You'd think JSF would just get fixed to align itself with web architecture fundamentals, but ok. The documentation describes how links are provided,
"We want to jump to a page containing item details, when the user clicks on the item link. The resulting detail page should be bookmarkable. The best way to accomplish this is using HTTP parameters."
Parameters are not the best way to do this in general, though they might well be wrt JSF. The documentation goes on to say:
" Now let's see how it's possible to invoke the action with RestFaces."
The giveaway word is "action"; unfortunately that's not REST style, that's RPC. Here's how action is marked up:
<rest:link value="item">
<f:param name="itemId" value="#{item.id}" />
<h:outputText value="#{item.name}" />
</rest:link>
which strikes me as quite cluttered; an "a" tag with href seems like a nicer option.
Looking through the rest of the documentation suggests that RESTfaces is dealing with incidental complexity introduced by JSF itself, as the majority of the examples are about managing internal wiring and mappings. RESTfaces as far as I can tell is an RPC technology. I've described the technique it's using to provide links as "CGI/RPC explicit" in the past. This is where you pass the id of the resource you care about as a query parameter to a script, instead of addressing the resource directly. In OO terms that's just like hiding all your domain objects behind manager classes and passing primary keys around - something that would be unacceptable for modern Java development.
I suspect RESTfaces does what it can to patch around JSF's limitations to provide bookmarks, but part of me wonders, why bother? JSF is clearly not focused on or suitable for working in the REST style to the extent REST principles seem to be actively excluded from the design. So, in the context of the way JSF does things, it's fine to add CGI style extensions for something as fundamental as linking, but then the REST moniker isn't appropriate. I understand I'm being hard on RESTfaces here; in fairness frameworks not being aligned with the Web is the norm and I'm reminded about what Mark Nottingham said about web frameworks:
"URIs are the lynchpin of the Web; to get the full value of the Web infrastructure, you need to be able to identify every interesting part of your Web application with a URI. Unfortunately, common Web APIs don’t encourage this, or even actively discourage it."
Struts2 REST
On a more positive note, Stefan Tilkov links to some material about REST support in Struts2; it looks like someone did some digging into the Web's design. Check it out.
SpringMVC + Restlet
Personally, I think unifying SpringMVC, RESTlet routers and JSR311 annotations would give you most of what you need.
If you've used Django or Rails, then SpringMVC has a controller/view request model that will be intuitive, while being familiar enough to the legions that grew up on Struts ActionController. According to Jurgen Hoeller's post, "Annotated Web MVC controllers in Spring 2.5", Spring 2.5 introduces some web annotations:
"So how does Spring 2.5's annotation-based controller approach fit into this picture? Quite simple: It is essentially an alternative controller type supported by the DispatcherServlet / DispatcherPortlet, not implementing a specific interface but rather using annotations to express request mappings for specific handler methods. It is primarily a next-generation style for implementing multi-action controllers, superseding Spring's good old MultiActionController class"
I think once you go down the road of using annotations such as @Controller and @RequestMapping for HTTP, you'll end up looking at JSR311 annotations.
Beyond JSR311, the best URI mapping I've seen in the Java space is RESTlet's Router API. Here's an example:
Router router = new Router(getContext());
router.attach("/users/{user}", UserResource.class);
router.attach("/users/{user}/orders", OrdersResource.class);
router.attach("/users/{user}/orders/{order}", OrderResource.class);
which is quite a bit more flexible than the default mappers shipped with SpringMVC. As an aside Guice Binders vaguely remind me of Restlet Routers. I'm guess I'm saying that your Java interfaces are merely Resource implementations ;)
9 Comments
I wouldn't be too hard on 'id' query string parameters. Yeah, they aren't as tidy looking, but they are still just as much part of the URL as path components are. The URL format doesn't really have much architectural significance.
"...which strikes me as quite cluttered; an "a" tag with href seems like a nicer option."
Are you advocating only coding in the expected content-type? Granted, having the natural representation for HTML is much easier to read and maintain, but that assumes text/html and no other. Also, applications can be very complex and having a one to one binding between development artifact and content-type may not be practical.
I agree with David. The syntax of an HTTP URL is just a clue about whether REST or RPC or some other architecture is being used. I experienced this when implementing an Atom Publishing Protocol server. My server uses "edit" and "edit-media" links of the form {collection-uri}?entry={atom:id} and {collection-uri}?media={atom:id}. It looks a lot like "CGI/RPC Explicit" but it is just as RESTful as any other AtomPub server that doesn't require that the atom:id of an entry be the same as its edit URI.
In particular, using links of the form {collection-uri}/entry/{atom:id} and {collection-uri}/media/{atom:id} would not change how my applications work at all, except making the web servers URL mapping configuration more complicated.
"The syntax of an HTTP URL is just a clue about whether REST or RPC or some other architecture is being used. "
Links of the form "{collection-uri}?entry={atom:id}" identify the collection resource, not the entry. The question mark in the URI is used to separate the URI from parameters which are appended to it to perform an operation. I understand this might not be a well known aspect of HTTP/URIs.
Bill, I consider you to be an authority on such matters, but I cannot find anything in RFC 3896 or RFC 2616 that supports that line of thinking. What am I overlooking?
RFC 3986 says "The query component contains non-hierarchical data that, along with data in the path component (Section 3.3), serves to identify a resource[.]" Basically, there is basically no distinction between "/" and "?" other than syntax and that segments between slashes have some hierarchical properties that query strings don't have. RFC 2616 gives no semantics to query strings whatsoever.
I am particularly interested in hearing of any advantages that your interpretation of query string semantics over mine.
Thanks,
Brian
I don't have time to dig up the reference now, but I believe Roy said on rest-discuss that the special handling of "?" URIs is a legacy and no longer relevant in practice.
The thread you are talking about is here: http://tech.groups.yahoo.com/group/re...
In that discussion, Bill brings up the point that RFC 2616, section 3.2.2 says "...the Request-URI for the resource is abs_path...." (omitting the query parameter).
There is a proposal for RFC2616bis to change this to include the query parameter:
http://www.w3.org/Protocols/HTTP/1.1/...
http://lists.w3.org/Archives/Public/i...
"There is a proposal for RFC2616bis to change this"
Yeah, they need to do that.
Wu9F1V sd89f984q34slf