users@jersey.java.net

RE: [Jersey] Hypermedia Support is useless

From: Markus Karg <markus.karg_at_gmx.net>
Date: Sun, 14 Feb 2010 19:02:39 +0100

Jan,

> just a quick comment on your 'solution':
> > A real RESTful application needs no actions to solve workflows like
> > the above. In the real world, if a company lives that workflow and has
> > no computers, they will forward paper documents: Review Orders, Review
> > Results, Cheques, Receipts, Shipping Orders, Delivery Notes. In fact,
> > due to usefulness, custom and legal / tax / customs regulations, they
> > actually have to archive those documents for several years. So when
> > replacing the paper process by an electronic process, you typically
> > won't change the process or it's parameters (the documents), but just
> > immitate it in an electronic form: Replacing the paper documents by XML
> > documents. If you would apply the RESTful pattern, you will come to the
> > following API by a simple 1:1 mapping of paper to electronic form:
> > Review: POST http://.../orders/1/ @Consumes xml/reviewOrder
> @Produces xml/reviewResult
> > Pay: POST http://.../orders/1/ @Consumes xml/cheque @Produces
> xml/receipt
> > Ship: PUT http://.../orders/1/ @Consumes xml/shippingOrder
> @Produces xml/deliveryNote
> I'd rather think about it like this:
> Review: POST http://.../reviewProcessor @Consumes xml/order @Produces
> xml/order (with link to review log maybe)
> Pay: POST http://.../invoicing @Consumes xml/order @Produces
> xml/invoice (but does the invoicing in the backend)
> Ship: POST http://.../shipping @Consumes xml/order @Produces
> xml/trackingStatus (starting the shipping in thebackend)
> Because I think that the resource that represents the order should not
> bother with starting other processes. But, of course, this depend a lot
> on the legacy systems and what components manage the orders and what
> components manage what processes.

I just wanted to point out that there is no need for a new API or new URI
style just to get what the example in the proposal wants. I didn't want to
propose exactly that solution.

About your proposed solution: I have to disagree. There is no need to name
the type of service or modification in the URI (there is no need to change
the URI in any way) just to get things done. By definition, it *is* the
client's job to trigger each single step, so it *has* the know what it must
do for that. My first proposal showed how that can be achieved using one
single URI by letting the client do the modifications. In case that each
modification is to be done by a service (what would be typical for payment
processes or shipping processes, as there are default services for that like
VISA or UPS), let me give the ultimate example how Fielding's dissertation
deals with that:

Fielding wrote that it is the client's job to control the workflow and store
the state. So if the server allows an object to be shipped by UPS and paid
by VISA, there would obviously be external URLs -- so there *cannot* be
modifications to the original URI! Remember that Fielding abstracted the
method of operation from a browser. What a browser would expect by manual
processing would be that (a) the user understands the title of each <a> tag
and clicks on the right ones, and (b) the <a> link typically would end at a
service provider but not on the original web server (i. e. directly by UPS
and VISA but not on the web server which itself asks UPS and VISA). As a
result, the same abstraction has to apply to a programmed client, and the
URIs would be:

     Review: POST http://www.some-reviewing-service.com/...
     Pay: POST http://www.visa.com/...
     Ship: PUT http://www.ups.com/...
 
The dissertation clearly mentions that workflows are typically invoking
*multiple* stateless services, and it is the client's job to call each of
them -- not the server's job! So the client must know the foreign services'
endpoints. So it makes no sense to modify the original URIs -- neither with
method names, nor with service names.

Regards
Markus