users@jersey.java.net

Re: [Jersey] Putting the RESTful "connectedness" around my existing Domain objects

From: Craig McClanahan <Craig.McClanahan_at_Sun.COM>
Date: Fri, 10 Jul 2009 09:56:46 -0700

Here I thought school was out for the summer, and wake up to find myself
back in philosophy class :-). A few comments interspersed.

Jason Southern wrote:
> 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.
>
>
Agree that the linkages stuff is missing (in the sense that there are no
annotations to generate the URIs for you). But can you define an
algorithm by which the annotation can actually do that mapping
(relationship -> URI), unambiguously, for every application use case?
That seems pretty ambitious to me, especially given that you might need
different URIs for the same resource to handle different representations
(as you outline below). And don't forget to generate an appropriate
media type at the same time.
> 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.
>
As above, I'm not sure how completely this can be generalized.
> 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?
>
>
This sounds like something I would do with separate MessageBodyWriter
implementations for the same model class. JAX-RS already provides the
mechanism to match up based on model class and media type, and the MBW
implementation is free to construct whatever representation it wants,
with access to whatever request specific context information it needs.

This might also be an avenue worth exploring to solve the bigger picture
problem presented in this thread. If you think of an MBW as a
transformation from a "data model" to a "view model", then maybe this is
the place to add in the additional links and that sort of thing. And,
of course, MessageBodyReaders can provide the opposite transformation.
> 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.
What happens when you need the same data model classes in more than one
web service, with different URI patterns?
> 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.
Actually, that hasn't always been the case in my experience so far.
Quite often I find myself needing to construct representations that are
simplifications of my data model classes (leaving out the password field
on a user record, etc.), or resources that are consolidations of
information from multiple models. For simple CRUD requests, I can buy
this statement -- but for more complicated scenarios, you quickly get
into all the impedance mismatches that any ORM solution has to solve.
> 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.
>
>
As a practical consideration, one thing to remember is that the
annotation classes themselves need to be visible on the classpath in
every application where those double-annotated model classes would be
used. Thus, you'd want to isolate the annotation classes into a small
separate jar, so that trying to use the model classes in a batch Java SE
app doesn't drag in all of Jersey.

Deep in history, someone tried something like this with ActionForm
classes in Struts 1, wanting to use them as a DTO-type mechanism in a
batch program. ActionForm itself, of course, is buried in the struts
jar, which pulls in JSP, which pulls in servlet, which pulls in .......

Craig

> Thoughts?
>
> Regards,
> Jason Southern
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>