users@jersey.java.net

Re: [Jersey] Question: Best practices related to Eclipse project structure

From: Craig McClanahan <Craig.McClanahan_at_Sun.COM>
Date: Thu, 05 Feb 2009 09:29:15 -0800

Andrew Feller wrote:
> Thank you Farrukh for your response!
>
> I am familiar with Maven and can relate to some of your own earlier
> experiences with it, however my employer doesn't have any plans to switching
> to Maven at this time.
>
> Could you elaborate on how Maven helps you structure your Jersey REST
> services? In particular, what kind of package layout do you use?
>
> In the past when we developed Struts 1/2 based applications, we would
> typically organize classes based upon functionality: POJOs, Actions, DAOs,
> etc. With the Jersey REST services we are trying to architect, the knee
> jerk thoughts we have come up with off the bat are: Resources (classes where
> REST requests are made to) and POJOs.
>
> I suppose another way to look at this question is: When developing a
> typical, complete Jersey REST service, what are all of the different
> elements that are required and what options for project layouts are
> available?
>
>
I can throw in some general thoughts about organizing things, based on
my experience with JAX-RS and Jersey so far. Let's start by identifying
the moving parts (with some comments thrown in about separation of
concerns):

* Data model classes -- typically tied to some persistence framework
  like JPA or Hibernate. Should *not* be tied to web APIs.

* Business logic -- implementation of the actual behavior of your service.
  Might be Spring-activated beans, might be EJB session beans,
  might be POJOs ... whatever your favorite paradigm is for this kind of
thing.
  But should *not* be tied to web APIs (for ease of testing). Will depend
  on the data model classes.

* Resource classes -- JAX-RS specific resource classes that basically
  map incoming requests to calls on your business logic methods, and
  then maps the return values from the business logic into responses.
  In a small application you'll sometimes see the actual business logic
  embedded here, but I prefer to separate it if there's any complexity
at all.
  My preference is that the resource class always accept and return
  entities that are your data model classes (rather than producing raw
  JSON or XML) and then rely on the JAX-RS providers mechanism to
  separate out the actual parsing and formatting logic. These classes will
  directly depend on your data model and business logic classes.

* Providers -- If you are not using JAXB-based data model classes, or if
  you have specialized needs, you should provide suitable
  MessageBodyReader and MessageBodyWriter classes to do the
  parsing and formatting. For JAXB-based data model classes, you get
  the providers you need for free, courtesy of the JAX-RS infrastructure.

If you think about it a bit, you'll see that any particular web service
call will probably require stuff from all of these categories.
Therefore, two different Java package architectures could easily make sense:

* Separate package for each of the above categories (data models,
  business logic, resource classes, providers).

* Separate package for each functional portion of your web service,
  combining related data model, business logic, resource, and providers.

Which approach to take is somewhat an aesthetic choice, and also
somewhat influenced by whether you want to leverage "package protected"
access between your various classes. But I generally tend towards the
first approach in my apps.

One further consideration -- are the all or some of the clients for your
web service going to be using Java? If so, a nice value add would be to
add a "client SDK" type module, which encapsulates the web service
calls. If you use Jersey Client for this, you can leverage the same
data model classes and providers that are used on the server side (so,
you would probably want to put those classes into different Eclipse
projects so that both the client and the server can depend on them).

You can see my notion of organization fleshed out in a sample
application that was recently added to the Jersey trunk. See the
contents (and README.txt file) of:

* samples/atompub-contacts-models -- data model classes shared by client
and server.

* samples/atompub-contacts-server -- REST web service somewhat like the
  Google Contacts API, but with no real database behind it.

* samples/atompub-contacts-client -- client SDK that can call the
various web service methods.

Hope this helps.

Craig

> Regards,
> Andrew
>