dev@jsr311.java.net

Re: Redirection and creation <was> Re: Container Independence

From: Dhanji R. Prasanna <dhanji_at_gmail.com>
Date: Mon, 16 Apr 2007 14:46:08 +1000

On 4/16/07, Jerome Louvel <jerome.louvel_at_noelios.com> wrote:

>
> I don't think that @Accept corresponds to the "Accept" HTTP header here.
> The
> "Accept" header list the media types accepted by the client, when the
> @Accept annotation lists those acceptable by the server.


Is this the same as @ConsumeMime then?

>The same
> > Representation can be used in a variety of different responses,
> > e.g. the same representation can be used in a 200 ok, a 201 create,
> > a 307 temporary redirect, ... Having everything together in one class
> > loses that separation but perhaps that is only important in my mind ?


This is all very well philosophically but the makeup of these classes and
their roles are significant. HttpResponse is quite a broad sounding
artifact. Can it be used to return representations? Is it only meant for
returning status codes or other response-specific headers? What parts of it
are used in particular use-cases (such as redirection) or is it abstract and
need to be derived for every use case?

To me, this is a design problem that looks like this:

- a core data object integral to the flow needs to be returned (response
"content" or representation)
- a set of metadata on *how* to interpret the data needs to be returned
(content-type etc.)
- a set of metadata on *what* the response is (status code)
- other metadata regarding *where* or *when* (location redirects, expiry
etc.)
- arbitrary headers (extensions?)

The possible high-level solutions proposed are:

- Annotate the core object with mixed arbitrary groupings of the metadata
- Provide multiple wrappered types inheriting from a base "Response"
- Collapse everything into 1 artifact (presumably a javabean with setters
for each meta/data item)

Aside from the annotations approach (which is a bit restrictive when dealing
with non-canon cases) the rest leave too much upto the developer to work
out. I would suggest the api should be more exemplary and guide the
developer. I like using a set of Builder patterns:

Response.respond(new MyDataObject())
   .as("text/html")
   .marshalledBy(MyDataObjectSerializer.class)
   .expiringOn(...)
   .foundAt("http://www.wideplay.com");
   //etc.

Now, the underlying composition can derive from a low-level HttpResponse or
be (similar to) a map of bindings (header -> value), but this is all
plumbing hidden from an end user (for the majority of cases).
The use of an EDSL (embedded domain-specific language) also gives us a
type-safe and readable high-level api as opposed to something like:

reponse.getHeaders().add("content-type", "text/xml");

//or binding to javabean properties:
setContentType("text/html");
setLocation("http://...");

Dhanji.