dev@jsr311.java.net

Re: Asynchronous REST service

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Tue, 15 May 2007 20:56:01 -0400

I think you could do most of what you suggest just using HTTP and
without inventing a receipt document. E.g. the response to the
request that starts the async processing could use the 303 status and
include a Location and Retry-After header. The client can then pick
up the results or an error response from the URI provided after the
time specified by the server has passed.

Initial request:

POST /processor HTTP/1.1
Host: example.com
Content-Type: application/xml
Content-Length: nnnn

...

Response:

HTTP/1.1 303 See Other
Location: http://example.com/processor/1234567890
Retry-After: 120
Content-Length: 0

Susequent request to retrieve response:

GET /processor/1234567890 HTTP/1.1
Host: example.com

Response:

HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: nnnn

...

Exactly how the back-end processing occurs doesn't concern us but I'd
think it would involve posting the request to a message queue or
something like that. You could implement the above with something like

@UriTemplate("/processor")
@ConsumeMime("application/xml")
@ProduceMime("application/xml")
public class Processor {

   @HttpMethod("POST")
   public Response process(Source xmlDoc) {
     int processId = enqueueRequest(xmlDoc);
     URI processUri = getProcessUri(processId);
     return Response.Builder.seeOther(processUri).header("Retry-
After",120).build();
   }

   @HttpMethod
   @UriTemplate("{id}")
   public Response getResult(@UriParam("id") int id) {
     Result r = findResult(id);
     if (Result.completed()) {
       return Response.Builder.ok(r);
     } else {
       URI processUri = getProcessUri(id);
       return Response.Builder.seeOther(processUri).header("Retry-
After",120).build();
     }
   }

   ...
}

Marc.

On May 15, 2007, at 8:00 PM, Hao He wrote:

>
> Hi,
>
> One of a very patterns we found is what we call "Asynchronous REST
> service" [1].
>
> "An asynchronous service needs to perform the following:
>
> 1. Return a receipt immediately upon receiving a request.
> 2. Validate the request.
> 3. If the request if valid, the service must act on the request
> as soon as possible. It must report an error if the service cannot
> process the request after a period of time defined in the service
> contract.
>
> Request Receipt
>
> An example receipt is shown below:
>
> <receipt xmlns="http://www.xml.org/2004/rest/receipt" requestUri =
> "http://www.example.com/xya343343" received = "2004-10-03T12:34:33
> +10:00">
> <transaction uri="http://www.example.com/xyz2343" status =
> "http://www.example.com/xyz2343?view=status"/>
> </receipt>
>
> A receipt is a confirmation that the server has received a request
> from a client and promises to act on the request as soon as
> possible. The receipt element should include a received attribute,
> the value of which is the time the server received the request in
> WXS dateTime type format. The requestUri attribute is optional. A
> service may optionally create a request resource identified by the
> requestUri. The request resource has a representation, which is
> equivalent to the request content the server receives. A client may
> use this URI to inspect the actual request content as received by
> the server. Both client and server may use this URI for future
> reference. "
>
> So, how does this case go with the current REST API?
>
> 1. http://www.xml.com/pub/a/2004/08/11/rest.html?page=2
>
> Hao
>

---
Marc Hadley <marc.hadley at sun.com>
CTO Office, Sun Microsystems.