users@jersey.java.net

Putting the RESTful "connectedness" around my existing Domain objects

From: Jason Southern <southern.jason_at_gmail.com>
Date: Fri, 10 Jul 2009 01:21:31 -0400

So, I started using Jersey after attending Paul and Mark's JavaOne
session on JAX-RS. First off, great presentation. I left JavaOne
interested in exploring REST because of the power of JAX-RS. It seemed
like a compelling alternative to the pain I've been suffering trying
bring along mid to junior developers even simple SOAP web services. I
took Mark's advice and read Ruby and Richardson's book and was pleased
to find the spirit of the ROA in Jersey.

While this thread has gone toward the philosophical, which is always
interesting, I'd like to turn it back around a little more toward
implementation, or in other words what can JAX-RS or Jersey offer me
the developer?

I began my foray into Jersey with this question. How does
JAX-RS/Jersey accelerate and improve my ability to develop a ROA? I
only found a couple of things to be missing, ease of promoting
connectedness in the ROA and the ability to produce different state
representations (not content-type) from a single Class.

Improvement #1: Promote connectedness through model URIs
I didn't see anything in Jersey 1.1.0-ea, the JAX-RS spec or the user
guides on dynamically producing URIs using annotations. So, I decide
to spend a couple of hours developing a few annotations to handle
mapping bean properties to URI segments (URI template parameters,
query string parameters). I then decided to wrap the UriBuilder and
add a factory method that takes an Object and builds a URI from the
annotations to achieve dynamic URI construction. I even added an
annotation for a URI description (in the event I want to represent my
resources in XHTML using <ul> and <a> tags). Voila, it works without
having a separate XML file. I think is a powerful approach to
promoting connectedness. I then stumbled across this thread only to
find out Brett had suggested just this thing. Brett, I'm curious where
you stand today 7 months after starting the topic. I'm happy to
contribute my code for further discussion once I complete the Sun
Contributor Agreement.

Improvement #2: Reduce the amount of code that has to be written to
produce different representations
I found this to be important when I discovered myself thinking about a
new class for each representation. Take a user entity. In some cases,
it makes sense to represent the user's state as username and password.
In other cases, it makes sense to also include usage data or personal
information. Should I create a new class for each representation just
so I can use JAXB to quickly output XML or JSON? What meaningful name
do I give the different representations? Do I use an adjective or
suffix to qualify the classes? UserInfo, UserSummary,
UserPersonalConfidential, etc. Will anyone understand this a year from
now?

I see Craig's point that merging the model and view can lead to
dangerous consequences, but in some cases, aspects of the view can be
programmed directly on the model using meta-programming. Take the case
when you decide that your resource has only one view/representation
and it matches your entity EJB exactly. How about the case when the
set of representations the resource needs to provide are only
different combinations of the entity EJB properties? Why add a second
model to the view layer just to preserve layering? Feels like I'm
violating DRY. I guess, I'm just not convinced that annotations that
serve different layers cannot be placed on the same model. I'm
comfortable with that because as James mentioned, in REST the resource
and entity are nearly synonyms. Since REST is more a set of principles
than a specification (and the reason why it so compelling when
compared to WS-*), why shouldn't Jersey offer this?

Obviously there could be some performance issues with this approach,
because of the amount of reflection logic that may be required to
combine JAXB and new JAX-RS "representation scope" annotations.

Thoughts?

Regards,
Jason Southern