dev@jsr311.java.net

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

From: Jerome Louvel <jerome.louvel_at_noelios.com>
Date: Mon, 16 Apr 2007 08:13:45 +0200

Dhanji,

> 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?

It does mean the same.

> 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?)

OK.
 
> 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)

I favor a combination of the first and the third option. For the third
option, I would call the artifact "Context" and it would also carry
additional request-related information. It can be viewed as a merging of
"Request" and "Response". Another name could be "Call".

This Context could be either injected manually, as a special input parameter
to a method, or instantiated manually and returned as an output parameter of
a method:

        Context postData(...);

> 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.

We experienced with this pattern in the Restlet API prototypes. The
reactions were mixed. I would use it only if the order of the calls doesn't
really matter.

> 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://...");

I think that we should provide a mapping from those important HTTP data to
high-level properties or annotations, we should not be too explicit about
the way they are mapped to HTTP headers (their semantics should be precise
however). This concrete mapping should be implementation specific.

If you want to see how these properties could be exposed, check the
Restlet's Request and Response objects:
http://www.restlet.org/documentation/1.0/api/org/restlet/data/Request.html
http://www.restlet.org/documentation/1.0/api/org/restlet/data/Response.html

Best regards,
Jerome