« Metrics and measurements | Main | Measuring SOA Success/Failure »

March 14, 2009

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d8345208e269e2011168f4c25c970c

Listed below are links to weblogs that reference REST Principle: Separation of Representation and Resource:

Comments

Jean-Jacques Dubray

Unfortunately Anne, the semantics of PUT are extremely clear (as defined by the RFC 2616):

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.

As you know a new version is a new version not an updategram. In addition, trying to infer an updategram (a.k.a as change summary) from a resource representation does not work. That's why people create thinks like SDO and XQuery.

Assuming that people will go with the PUT semantics and implement a "replace", it now creates an extreme coupling between the client and the server -as the owner of the resource. To implement PUT correctly, the server must share a complete resource representation (how practical is that?), and of course process a similarly complete resource representation to replace the original one (even more practical, right?).

In a connected system, A CRUD interaction pattern (even based on updategrams, not to mention entire replacement of the resource) is the absolute worst possible interaction pattern between a consumer and provider. As it create the absolute worst coupling possible.

If this is however the way you recommend people do SOA, or even ROA, I have a suggestion, why not expose SQL endpoints? That way you get the power of the relational model (no more navigational stuff -as you mentioned in your post, it is not really practical to create child resources just for a single attribute) and with SQL you can CRUD as much as you want. By the way, the SQL Update is far better than a PUT, IMHO.

Incidentally, if you are creating, as you are suggesting, "partial" representations, aren't you actually "sending a message" to the original resource?

Of course, we can always claim that HTTP is not entirely "RESTful", hence the semantic of PUT is not reflecting the power of REST, but I thought that the beauty of REST was that everything was readily available and we did not need to buy any expensive middleware. How much do you think vendors will charge us for RESTful middleware?

So I am not sure where you want to go with this kind of discussion. There are two interactions paradigms:
a) message oriented
b) CRUD oriented

long, long ago, people have discovered that message oriented is far superior to CRUD. They have even paid lots of money to implement infrastructures that send and receive messages. Some people have even added higher level semantics to these messages like RPC, Query/Response, Event Notifications, Transactions...

Do you think it is really reasonable to return to the CRUD days? what will we gain?

Anne Thomas Manes

Jean-Jacques: I think you misunderstood my message. I'm not suggesting "partial representations". I am suggesting that a widget's status is a resource in and of itself, with its own URI that refers to that specific widget's status. It's a first class resource, so you can GET and PUT the widget's status, just as you can with any other resource. When you PUT an entity to the "status" resource, the server SHOULD treat the entity as a request to update the state of the resource. It's not a matter of "new version" verses "updategram". The supplied entity contains a representation of the widget's status. Your server needs to accept that entity and "store" it as a replacement for the existing "status". Remember that the widget's status is an abstract thing. The XML document is simply a representation of the resource.

Jean-Jacques Dubray

Hum... there is a lot of back and forth in your post, even in the conclusion and frankly I could not beleive you would make this kind of recommendation.

Nobody in the world is going to let a consumer CRUD the state of their resource. The French Bank Société Générale enabled that as part of their trading systems (not in a RESTful way though, just pure CRUD) and they lost $7B, quite a hefty price for a little CRUD, as a resource consumer was able to CRUD the resources (trades) in a state that made them invisible.

Now when you say: "When you PUT an entity to the "status" resource, the server SHOULD treat the entity as a request to update the state of the resource" you are twisting the semantics of PUT, this is not a "new version". Only YOU say that it is a request to update, not RFC 2616. When I create a new version of a Web Page or a word document, I don't "update" that Web page or document, I am sorry. PUT does not have the semantic of a "Request", it has the imperative style of replacing that resource with the new resource representation, which implies I have a "complete" representation (be it of the status or the parent resource itself).

Unfortunately though, there are no evidence of a Resource Oriented programming model. It either boils down to:
a)CRUD which everyone will dismiss (can you imagine the number of queries you have to make to "GET" a resource representation if this resource representation is broken down in a set of common denominators of "updategrams"?, not to mention the transactional requirements in imposes on the programming model).

b) POST with the semantic of a message (PUT does not have the semantic of a message) to the target resource. This is implemented typically with a Command Pattern within the target resource's business logic.

There is simply no evidence of a Resource Oriented programming model, I am sorry.

Anne Thomas Manes

I have to disagree with you Jean-Jacques. There definitely is evidence of a resource-oriented programming model. The semantics of GET, PUT, POST, and DELETE on a resource model are not the same as the semantics of CREATE, READ, UPDATE, and DELETE on a relational model. Perhaps this strong association in your mind is the root of your rejection of REST.

A resource is an abstraction. It is a named entity that refers to some state that is maintained on the server. Users interact with a resource through various representations, but a representation is not "the" resource. It is simply a representation. As a resource-oriented developer you should maintain the separation of concerns between the resource and its representations.

A resource may have multiple names (i.e., URIs are not unique identifiers). A group of resources may refer to different aspects of a larger entity (e.g., a widget, its status, and, its color). A resource may refer to a collection of things (e.g., all widgets colored "Red"). In many cases, a resource does not not map directly to a file on the server. Very often the state of the resource is dynamically created. For example, http://www.time.gov/timezone.cgi?Eastern/d/-5/java refers to the current time in the US Eastern Time Zone. Obviously, the current time is not coming from a file.

Bear in mind that the specification says "SHOULD", which gives the developer a certain amount of leeway in determining how to process a PUT. It does not mean that you MUST replace the existing server state with the *exact* representation supplied. It means that you SHOULD replace the current state with the state supplied.

As I said, a widget's status can be defined as a first-class resource. That resource might be related to other resources (e.g., the widget), but you absolutely can perform a PUT on the widget's status resource without also performing a PUT on the widget resource. (Note, though, that updating the status resource, in this case, will also update the widget's state.) If you maintain the state of the widget in a database, then when a user updates the status via PUT, the server updates the Widget's status tuple in the database. If you maintain the state in an XML document, the server updates the appropriate element in the document. My point is that it's your obligation as a developer to hide the physical nature of your storage media from the user of the resource.

Jean-Jacques Dubray

Anne:

thanks for the precision, I think we should be very clear if we are talking about REST or HTTP. The semantics of PUT are not defined in REST but in the HTTP specification, and agreed, they are a subset of CRUD, but as such they are CRUD. In other word, PUT is not "update", it is "replace", which is worse then "update" because it forces you to "GET" a complete set which you will manipulate on the consumer side and "PUT" back on the server. You can twist HTTP any way you want but the principles of a specification is precisely that you can't do whatever you want.

Do you really see it as a viable strategy to break down resources into individual updatable components? Do you really think that developers will go for that? This creates problems in "GET", as you need to get a bunch of things (no joins in HTTP) and creates transactional integrity problems as well. So I am not sure how you can go in that direction. I actually can't believe that anyone would recommend going that way.

Now with respect to "representation" vs "resource", I want to emphasize that the semantics of PUT (if you use it) are incompatible with representations not being a complete set of data that you can "PUT" back as a new version. You might create different "formats" as representations (XML, HTML, PDF... which by the way was the intent behind REST), but "PUT" makes it very clear what a representation is, when you use HTTP.

So again, we can say whatever we want REST is (since it is just contraints), but RFC 2616 is not just ether. Dragging people behind the REST banner behind poetic interpretations of this standard is not necessarily something I view positively.

If now, you want to find "justifications" for people to do POX, or XML-RCP over HTTP because they have some stack fatigue (WS-* that is), fine, but let's be clear as technical professionals about what is what and what is a particular technology can do. "Updategrams" are not part of HTTP no matter how you look at it, even though the Web Services stack had SDO (including SDO.Net) for several years now.

Trying to convince people that HTTP does everything you'll ever need: "you just have to learn to program in a resource oriented way" is beyond me, and frankly, saddens me.

Jean-Jacques Dubray

Anne:

I don't necessarily disagree with what you are saying. But I think it the Resource Oriented Programming model requires a lot more evidence.

GET and POST are clearly messages to the target resource (albeit with different properties)

The meaning of "SHOULD" is defined as:
SHOULD This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

The "leeway" does not really play in favor of the RO programming model.

Ultimately is means that you can:
a) use it with the "replace" semantics
b) use some leeway but you have to define an "updategram/change summary" language. Do you do that on your own? do you need a standard?
c) use the approach that you are suggesting which is transforming the PUT semantic from "replace" to the one of a message, in which case, you are back to wonder why not use POST then.

Unfortunately, a programming model is a programming model and the more "leeway" you leave the more out-of-band agreements you will need, there is simply no other way around it.

Anne Thomas Manes

I'll give this one more try Jean-Jacques. From a conceptual perspective, doing a PUT on the widget's status resource is no different from doing a setStatus operation on a widget object. The fundamental message I'm trying to make is that you must maintain a separation between the representation and the resource. The resource is state, not a physical representation. The server that manages the resource is responsible for managing that state. The means by which the server manages the state should be invisible to the consumer of the resource. The server can expose multiple resources that enable the user to interact with the server state. The resource model exposed is conceptually equivalent to the methods exposed by an object oriented system. i.e., the resource model *IS* the interface. Hence PUT Status is equivalent to setStatus.

I should also reiterate that GET, PUT, POST, and DELETE have different semantics from CRUD. The operations do not map one-to-one.

PUT supports two CRUD operations: CREATE and UPDATE. (and by the way -- UPDATE in CRUD is equivalent to "replace") Note also that POST supports CREATE, but it does not support UPDATE (i.e., "replace"). POST when used to perform an update function means "process this", which is not the same as UPDATE.

The fact that PUT means "replace" rather than "update" is a good thing. It means that the operation is idempotent. You can set the status to "final" a dozen times, and the status will always be "final". That's quite different from POST. e.g., you could say POST [promote], which would promote the status to the next level. Such a command is not idempotent. It would be equivalent to an operation like updateStatus(promote).

Jean-Jacques Dubray

I again, there is nothing wrong with what you are saying, after all you 'can' do whatever executes without generating an execption.

I just want to point out that Roy has invalidated your interpretation of PUT. This is what he wrote in his last post (in the comments):

we only use PUT when the update action is idempotent and the representation is complete.

The fundamental questions are:
a) is the approach you are recommending working in all cases (You can set the status to "final" a dozen times, and the status will always be "final"), obviously the answer is no, the server is responsible for taking the decision to set the status, not the client

b) Do you have to clearly (hence semantically) distinguish between an "Replace" and the request for an action, for me, and I think for Roy, the answer is yes.

It is IMHO, not practical to flip flop between PUT and POST, or to use PUT for both a request for action and a request to replace the content of the resource.

So, I repeat,
a) the (other) REST is a fallacy (not the Web REST, which is perfectly designed)
b) Throwing countless of developers against the (other) REST wall equiped with an extremely weak programming model (and made up semantics) is criminal.

Anne Thomas Manes

Jean-Jacques: Roy has not invalidated my interpretation of PUT. I think you are misinterpreting my example.

If the current value of
"http://my.example.org/widgets/1234/status"
is "Pending", and I PUT a value of "Final" to that resource, the operation is both idempotent and the representation is complete.

I send a request to the server to replace the current value ("Pending") with a new value ("Final"). If I send the request a
second time, I'm still asking the server to replace the current value with "Final".

So yes:
a) The approach works in all cases.
b) The request follows the semantics of PUT.

Notice that the resource in question is the widget's status, not the widget. The status resource contains a single value representing the current status of the widget.

I could do a similar operation using POST on the widget resource:
POST http://my.example.org/widgets/1234
status="Final"

In this case I am asking the server to update the widget resource and asking it to set its status to "Final". But this is a much less RESTful way to do it.

Jean-Jacques Dubray

Anne:

I think we are playing with words. You are saying, that "PUT" has the semantic of a "request" when in reality it has the semantics of "Replace". Those are two very different things. I don't know many people that would trust their "consumers" position their resources in a certain state, they would only trust them to request a transition to a given state. You just can't make up semantics, a PUT is a PUT, nothing less or nothing more.

It is sad to see decades of software engineering progress being washed away so easily and the introduction of an extremely strong coupling between the consumers and the providers based on a CRUD mechanism.

Have you ever thought about the implications of using one end point per resource and now one endpoint per action invoked one a resource? How do you version your business logic? How about management and monitoring? Where are the boundaries in REST?

>> In this case I am asking the server to
>> update the widget resource and asking it
>> to set its status to "Final". But this
>> is a much less RESTful way to do it.
I don't think that this is what Roy is saying, read the title of his post: POST is OK…right? I think using a PUT is the most catastrophic way to do it.

Look Anne, at the end of the day, what is happening here? The semantics of connected systems are independent of a particular middleware approach. No matter which middleware approach you choose, you will have to reify these semantics one way or another with the semantics of your middleware (RO, SO, RPCO or EO).

It is sad to see the RESTafarians damage such a superb piece of work (Roy's REST) and establish a CRUD relationship between consumers and providers. Roy had opened the way and showed the value of an "application protocol". By carefully analyzing the requirements of the Web he invented the perfect application protocol for the Web.

Couldn't we take the same approach that Roy took with the Web and adapt it with the requirements of Enterprise Systems? Do you really think that serendipitously, an application protocol designed for "Web pages" is going to work for "Enterprise Data"? Isn't there some minor differences between them? Haven't you ever looked at the state diagram of a Web page? How does it compare with the state diagram of a purchase order? an Invoice? a Service? yes, one sees a lot more states and transitions, hence a lot more actions. Some actions are idempotent some are not. It has nothing to do with the “VERB”, it has to do with the state machine of a PO, Invoice, ... and yes for a Web page, GET and PUT are idempotent and POST, well POST doesn’t really apply to a Web Page.

Again, I repeat, all these little "RESTful" vs "RESTless" discussions should give you a hind that REST does not apply to Enterprise Systems, you just can’t reify these semantics, only the approach that Roy took should be reused. In the mean time, we are throwing developers and architects against a wall, similar to the Stored Procedure wall, or the MVC wall. Eventually, you create so many artifacts be it with REST, Sprocs, Models-Views-Controllers that your system becomes unmanageable. Those are the “bubbles” of the software industry. One day they eventually burst. RESTafarians dismiss “reuse” as a primary concern of software engineering. This is precisely the problem. Reuse will only happen when Resource Orientation, Service Orientation and Event Orientation will be articulated to work together, in a true enterprise application protocol. Until next time, happy CRUDing

JJ-

John Scott

I found this an interesting post (PUT?). First it made me think that the representation I would PUT to a URI does no t have to be the same as the representation a GET returns - i.e. I could put a new state but a GET would return the whole resource - but the PUT semantics discussed imply I can't (shouldn't) do this. The answer seems to be to have a separate URI for each attribute - status, colour etc. Then I think about transactional integrity - how do I ensure the status and the colour are changed or neither. If I put a new status to "coloured in" and then fail to put a new colour of "red" then I am in an inconsistent state - even if I try n times and fail, it is inconsistent and somebody else doing a GET would see the status of "coloured in" but no colour :-(

Am I right in thinking that I need a separate URI for combinations of attributes I might want to change together - e.g.

http://my.example.org/widgets/1234
http://my.example.org/widgets/1234/status
http://my.example.org/widgets/1234/colour
http://my.example.org/widgets/1234/status_and_colour
etc???

Jean-Jacques Dubray

John:

you are correct, this is why the "Resource Oriented Programming Model" is a lure. It works well for "Web" resources because they have a very simple lifecycle and update behavior, but it shatters for Enterprise Data. It would amount saying that all we have developed in the last 30 years of OLTP was a mistake and REST is offering innovative and simple ways to deal with old and complex problems.

The reality is simply no, there is a principle of conservation here that REST cannot and will not overturn. Saying otherwise is simply criminal. Can REST do some simple things simpler, why not. But can we really do without an interface definition, robust versioning, runtime governance? No, you can't built enterprise class connected systems that way. Telling people that hacking a URI syntax and using HTTP is the end of all their pain and aches is once more selling hot air, and pushing IT towards less ROI and bigger mess.

The comments to this entry are closed.

  • Burton Group Free Resources Stay Connected Stay Connected Stay Connected Stay Connected



Blog powered by Typepad