According to Fielding's dissertation, the returned document itself must
contain the list of URL that the client can call. The client will only
select from those, but will not modify them. This cannot be supported by any
framework, unless the framework knows how to put URLs into a particular
media type. This is exactly how the web works: You get back HTML, and it
contains <a> and <form>. The browser will not modify them.
Note: "State != Content"! In fact, *only* the browser is storing the state,
not the server. The server typically is stateless, and one possible
implementation of a server *might* store *content*. But this is not
necessarily the case. Think of the process of VISA card validation: The card
to validate is sent by the client, and the client will keep the result
returned. VISA will only do a service (checking the validity by looking up
information known about the card or the owner), but not store any state of
the validation process itself.
See his blog entry about that topic:
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Regards
Markus
From: Kevin Duffey [mailto:andjarnic_at_yahoo.com]
Sent: Sonntag, 14. Februar 2010 20:24
To: users_at_jersey.dev.java.net
Subject: RE: [Jersey] Hypermedia Support is useless
I am a little confused Markus about your "modifying" the URIs? If the server
responds with specific URIs to be called.. the client is not modifying
them.. the client simply calls them?
I thought what the proposed additions to Jersey were trying to do is make it
easier for server side developers to return JUST the URIs that can be called
based on the context of the current request. If they POST a document (or a
form, file, whatever), the response should be one or more URIs that they can
use.. such as viewing the posted document, editing it, etc. This is very
much like how current web sites work.. I get back a page full of links.. I
can click one, and only one of those links to do something next. The browser
(client) doesn't modify those links..it displays them. The end user clicks
them. As far as I can tell, that is what HATEOAS is all about.. the server
does some logic to figure out the specific URIs to return based on the
context of the request being processed.. thus allowing the next set of
possible operations that can be done. Maybe I am not fully understanding
what you are saying. I think we may need Roy to respond with regards to the
issue of the client storing the state. I don't believe browsers store state
that is currently on the server?? What am I misunderstanding?
--- On Sun, 2/14/10, Markus Karg <markus.karg_at_gmx.net> wrote:
From: Markus Karg <markus.karg_at_gmx.net>
Subject: RE: [Jersey] Hypermedia Support is useless
To: users_at_jersey.dev.java.net
Date: Sunday, February 14, 2010, 10:02 AM
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
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
For additional commands, e-mail: users-help_at_jersey.dev.java.net