World Wide Webber


My Books
REST in Practice: Hypermedia and Systems Architecture
Amazon:
US, UK
Developing Enterprise Web Services by Sandeep Chatterjee and Jim Webber
Amazon:
US, UK,
Also available: Korean Edition

My Bookshelf
RESTful Web Services Cookbook by Subbu Allamaraju
Programming Clojure by Stuart Halloway
RESTful Web Services by Leonard Richardson and Sam Ruby
The Limits of Uniform Interfaces
Posted: 20 September 2004 @ 16:29 UT from Sydney, Australia

In an attempt to understand the position of the Web Services folks, Mark B. asks, "What's the simplest task that cannot be coordinated using a uniform interface?" I think this is a very profound question and one which should have Web Services people doing some soul-searching.

I'd like to turn this back on Mark though, and ask "What is the simplest task than cannot be coordinated using ProcessMessage ?" That is, if I can do something with one "verb" why does the REST community think it needs all these verbs?

Comments:
#
ahh, but the nice thing about having a few verbs, with explict rules about GET and HEAD being idempotent, is that it lets a vast caching infrastructure cache stuff for a while. That is, unless whoever implements the back end doesn't read and understand the rule about GET being nominally side effect free. Perhaps ws-transfer is secretly a plan to create HTTP/2.0; one built on WS-*.
#
Hey Jim. Easy question! 8-) Requesting data.
#
Hey Mark. That's not something that can't be done with processMessage though. As Steve points out, the infrastructure in the REST version of this problem can do caching, but then there's nothing to stop the service that provides the requested data from caching either - processMessage is therefore democracy in action :-P
#
But it is something that can't be done with ProcessMessage! With only ProcessMessage, all services are data sinks. It's just like email; you can't get any data from an arbitrary email address, only send data to it. To get data you need to do additional coordination, and then you're no longer using ProcessMessage.
#
Mark, don't be daft. It just takes two messages (request-data and data).
#
The fact that you can get data directly from a service/resource causes what i see the problem with REST. There is this association between the address/reference and the data (or its representation). Service-orientation and ProcessMessage makes you think in terms of the name of data. The introduction of an interaction helps with loose coupling. As Jim says, getting to the data is just a combination of two messages that can be combined together in a transport-protocol indepedent manner. For example, an email request to get access to my bank account info, and I receive a text message to my mobile with the requested info. This is described as a message exchange. With HTTP, GET couldn't be used (it's request/response). You could, of course, POST your request, receive confirmation that the request was accepted (request-response), and then receive the text message on your mobile. This means 3 messages with the third one not described anywhere as part of a message exchange pattern. Someone has overloaded the semantics of POST to the particular resource to explain what would happen. Do you see how ProcessMessage is more flexible than REST?
#
There's a lot more to this than meets the eye, Jim. It takes a lot more than two messages, it takes a contract that defines the shared expectation that the a certain kind of action will result - in this case, that a query document in, will result in the results of that query, out. ProcessMessage doesn't define such a contract (or if you think it does, then there's lots of other things it can't do). So while it's true that some service may respond to an inbound query document without an outbound document that includes the results of that query, it is not part of the contract and therefore just as likely that the query document was shoved into a database, or printed out on a printer, or ... Consider email. How can you, without additional coordination, request data from an email address? You can't. You can send an XQuery document to somebody, but who says they're obligated to process it and return the results to you in some way? And who says that any results you get has anything to do with the query document that was sent? Nothing. If you want that expectation, you need to extend the protocol to support an additional application semantic. That's why HTTP has GET, so that data retrieval can be performed without additional coordination.
#
Hey Mark. In the REST case you get the contract for free, that's fair enough. But ProcessMessage can also be contrained by using WSDL or similar. This contract is no stronger or weaker than the REST contract (who says that the thing you GET on will have implemented it correctly?).
#
Hi Jim. Well, my attraction to ProcessMessage was based on its uniformity. What I hear you saying there is that you can use WSDL to redefine "ProcessMessage" to something specific like "getBackAccountInfo" (per Savas' example), yet do it without having to include that operation name in the message. To me that's just the model that most Web services proponents have been pushing for the past couple of years, and the one that I think is actually architecturally *worse* than RPC, since it's not self-descriptive (see the "RPC using documents" part of http://www.markbaker.ca/2002/09/Blog/2004/07/28#2004-07-learning-curve2). Say it ain't so, Jim! 8-)
#
Mark, I agree with you that the model is not descriptive since it's not carrying application-specific semantics. This is left to the documents which describe the semantics of the message exchanges. WSDL describes the messages formats and the message exchange patterns but the semantics are actually described in the specifications of the messages (the namespaces in which they defined). If you happen to process a document which is defined in the namespace ns:example and you get element "X" then you should really reply with a message of this form, etc. It's the application domain-specific protocols that define the semantics of the message exchanges and not the WS infrastructure which is hihgly flexible.
#
It ain't so Mark :-) WSDL is a nicety and procesMessage works very well without it. However as Savas points out above, you can use WSDL to declare the message exchanges your service will understand - but the semantics of a message exchange still derive from a combination of the message and the service which processes that message and *not* on some "operation invocation."
#
Hmm, more miscommunication, rats... I'm not talking about data semantics, but interface semantics. So, let me try something else. To demonstrate that Savas' banking example doesn't present a uniform interface, let me ask a question; does this service provide clients the expectation that upon submitting a description of the desired banking information, that the information will be provided in another message? If so, then this would be a different contract that a service which took the same kind of banking information, and just shoved it in a database (though without providing the *expectation* that it do so). Therefore, we're dealing with two separate contracts.
#
Mark: Both activities could be part of the same application-level contract (<give-me-baking-info-message/> and <store-this-banking-info-message/>) just like they are in REST (GET [banking information], PUT [banking information]). The difference is that the messages in the processMessage case convey all semantics, the interface is semantically transparent and this is not the case for REST.
#
Whoa, that's a big surprise. My understanding was that "ProcessMessage" was to be the implicit operation that is used, yet now you're saying that "give-me-banking-info-message" and "store-this-banking-info-message" are operations. Sorry, but that's RPC. What I had in mind with ProcessMessage was that the message was just a document, i.e. the banking information, and there was no operation to be found anywhere, just a document being processed by a document processor.
#
Mark - you're being unduly alarmist. I appologise for giving my messages a name which might lead you to believe that it is RPC, it isn't. It is the form and content of the document which the service uses to guide its processing. You can indeed send a banking information document and the service will act on this - you positively cannot tell the service how to process this document like you can when you call a particular operation in RPC. However it might be sensible to use names for elements in messages which are indicative of their intent I think?
#
The rule of thumb that i always used when I design my documents to be exchanges is... "no verbs in the names of the elements". This means that we only model the exchange of document, of information. The interaction patterns are modelled through metadata rather than by the semantics of an-application-protocol-to-rule-them-all. That's why we think that "ProcessMessage" is an even more general and flexible architectural style than REST.
#
Well, I am quite alarmed! 8-) But when you say "you positively cannot tell the service how to process this document like you can when you call a particular operation in RPC" I am once again encouraged, but then I no longer understand how Savas' example works, because there seems to be an expectation on the part of the client that submitting a certain kind of document will result in a certain kind of behaviour. As I see it, the primary value of a generic interface like ProcessMessage is substitutability; that I can swap any service in for any other without breaking anything. Makes sense, right? Yet if I wrote code to use Savas' banking service, I can't swap in the aforementioned bank-info-storage service because it can't meet the same expectation that Savas' client has (and presumably presents to the user, i.e. "enter data here, hit submit, and *expect* an SMS message in response") about effecting a response message. Savas' "no verbs in the names of the elements" is a good rule of thumb, but IMO subordinate to the value of being *very* careful to stick to a single contract; it is *very* easy to stray to a different contract and not even recognize it. The fact remains that a uniform document-sink semantic - be it ProcessMessage, HTTP POST, or SMTP DATA - does not provide the expectation which is inherrent in any request for data. FWIW, this was the hardest thing I had to learn about REST. It took me about 2 years after I grokked everything else to understand it. I finally learned it by focusing on substitutability and expectation/contract matching.
#
Mark, great stuff :-) I think the reason you get alarmed is because you assume that the contract, which describes the message exchange patterns, is closely coupled with the underlying architecture. That is not the case. The architecture is based on one-way messages being sent from service-to-service and being received by a logical "ProcessMessage" operation. The fact that a contract is in place to allow services to agree on the message exchange patterns is indepedent of the architectural style. The "bank account info" example indeed looks like an RPC but it's not really. It's two one-way messages being logically associated through some higher-level semantics, the contract. Even in REST you'd have to do something similar. There would be a contract, a document somewhere describing the fact that once you POST a particular representation something equivalent will have to happen. This is not specific to REST but of the application that is built on top of REST. The same applies with the "ProcessMessage" model with the difference that it's only requires one verb and it uses only one-way messages. There may be cases where the contract defines output-only messages (e.g., notifications) or one-input/multiple-out messages (not your typical RPC) or anything you want. You can think of many different/interesting message exchange patterns that a _distributed application_ will define for its purposes. It is definitely the case that we can change implementations as long as the contract is maintained. The "client" (note that we don't use this term since everything is a service with a "ProcessMessage" operation) will never notice the change. Also notice that services interacting with one another bind on the messages and reason in terms of message exchange patterns. They don't bind on remote implementation-specific dispatch mechanisms.
#
Savas, I don't think I'm making such an assumption. I'm looking at this purely from an abstract POV where services present contracts, period. Re the bank example, you state "It's two one-way messages being logically associated through some higher-level semantics, the contract" - but the contract isn't higher level, since it's only by presenting the same contract that substitutability - the ability to swap one service for another without anything breaking - can be achieved; the contract is front-and-centre. REST doesn't have anything similar, since all services expose the exact same contract. In my view, "ProcessMessage" included a single contract; if it doesn't, I'm far less interested in it. So let me ask just to be clear; in your view, can any ProcessMessage based service be substituted for any other?
#
Yes, indeed it can be replaced. However, what you'll achieve is that the message will be received and processed. Nothing else will happen if a contract is not in place (you don't get a response for example). This depends on the underlying transport of course. If you use HTTP, "ProcessMessage" means that a message can be delivered for processing using HTTP PUT/POST. Using TCP/IP, it means that a message can be delivered for processing using send()/receive(). Using SMTP, it means that SMTP DATA is used. Any implementation can be used to receive the message. However, receiving and processing the message doesn't really suggest anything that is interesting to the application since not the "right" thing will happen without the knowledge of the _application-specific_ contract. This is not dissimilar to REST where I can replace one Web Server with another. Just because the Web Server can process HTTP requests, it doesn't mean that the correct thing will happen by the logic behind it, after the replacement.
#
Thanks for the interesting discussion! With ProcessMessage there can be no "generic" browser, right? REST comes with a standard GET verb that allows any Web browser to usefully do something. (Any maybe more with forms and POST.) Any ProcessMessage integrations (with a new service contract) would _always_ require custom development, right? If this logic is right, then isn't ProcessMessage listening for structured messages and dispatching on a part of that structure? (Just like HTTP Method dispatching...) If I'm still on track here then the underlying differences are: * XML vs RFC822 * No Contract vs RFC2616 HTTP Methods I think that the first one is important, but not crucial. The second one boils down to the value of including the contract or not.
#
Savas, this is great, we're really getting somewhere from my POV. You wrote "However, what you'll achieve is that the message will be received and processed. Nothing else will happen if a contract is not in place (you don't get a response for example)". In my view of how ProcessMessage should work, "received and processed" *is* the contract, but that doesn't mean "Nothing else will happen", all it means is that what happens is an implementation detail not reflected by the contract. The "received and process" contract is the uniform contract that I'm after; that I'd like ProcessMessage to mean, as well as the one already implemented in HTTP POST and SMTP DATA. That's why I felt it important to point out above that you can't substitute the SMS based bank service with the with the service I mentioned which stores the banking information; you can't substitute them because they are using *different contracts*. FWIW, I don't agree with the role you described there for underlying protocols, but it would probably confuse things to bring that up now - we can do it later.
#
Mark, I agree. The banking-related contract is application-specific. You can only replace the implementation of the service with another implementation of the same application-specific contract. The "ProcessMessage" has the same semantics throughout the architecture. However, I don't see why this can be an issue. You have the exact same problem with REST as I said in my comment above. The semantics of the architecture are shared throughout but once you start going to application-specific ones, you start having the same problem. But that's fine IMHO.
#
John, indeed you can't do a generic browser with just "ProcessMessage" but you can build a Web-like application protocol on top of it if you wanted to and at the same support all the other applications. "ProcessMessage" takes the idea of document exchange and moves it to its extreme by requiring that message exchange patterns are built only through the combination of one-way messages (no request-responses through the same communication channel). It's not difficult to come up with a message-oriented protocol that defines a "page-request" message which would result to a "page-contents" message (look at WS-Transfer). In fact, such an approach may be better for the Web since it would be transport indepedent (sorry Mark... the transport thing again :-)
#
Savas, you really don't have the same problem with REST, because with REST all services expose the same contract. That's the secret sauce, and I thought ProcessMessage did the same, which is why I was excited about it.
#
Mark: You just made it click for me I think. ProcessMessage services all expose an interface which looks something like void processMessage(XmlNode); which is uniform. Now, just like in the REST case, you might want to advertise which the format of messages the service can be expected to deal with. A useful analogy here is a shop. All shops have a pretty uniform interface, but each helpfully advertises additional information like kind of goods it sells. So ProcessMessage and REST (and shops) have a uniform network-level interface, but each "instance" of a service might declare application-level contracts on top of that - I need to understand the message schema even in the REST case right?
#
Yay, clicks! 8-) Yes, with REST you still have the problem of understanding the schema, I just don't consider that part of the contract that we've been talking about. But if that's what you mean by 'but each "instance" of a service might declare application-level contracts on top of that ', then I guess we're in synch. So, back to the initial message in this thread; do you see why there's no way to request data from a service using only the single, uniform ProcessMessage contract?
#
Hey Mark, Yes I do: ProcessMessage doesn't have a GET which can return a serialised version of a resource. That would be up to the "application-level" to figure out. This is, of course, a good thing since exposing resources and being able to GET them leads to the 404 nightmare.
#
How does ProcessMessage differ from TCP/IP?
#
Hi Mike. Good question, and the answer is that TCP/IP is one protocol onto which ProcessMessage can be mapped. ProcessMessage is intended to be a logical operation within a software architecture (a sink for messages within that architecture), which can be physically mapped onto any suitable underlying transport/transfer protocol.
#
> This is, of course, a good thing since exposing > resources and being able to GET them leads to the 404 > nightmare. What nightmare?
#
Hi Mike. The nightmare that my resource representations change as my service is maintained. I don't want to publicise any of my internal workings, and I definitely don't want people outside my service to bind to them, otherwise when I perform maintenance I will break their applications with a 404 or its moral equivalent. So: you can be relatively happy about the fact my service will be permanent, so go ahead an bind to it. You have no guarantee that any resources in my service will be around for any length of time - they are my private resources - so binding to them is risky, especially since I probably won't provide "redirection" when they disappear or change because it's an overhead.
#
Jim, Just after some clarification: it seems to me that ProcessMessage is a message dispatcher - takes messages and passes them to consumers/processors. Up to a point, this means a service provider can modify/evolve message consumers without disturbing message senders. Then there is an application-level contract that describes what to expect in terms of the externally-observable behaviour of a service. It is this contract that a message sender binds to. So, from the point of view of an application that depends on this binding, 404-like nightmares can arise when a service (or message consumer) evolves in some way that breaches contract or when a contract is evolved to no longer support some expected behaviour. Is this right?
#
Hey Nick, yes you're right. The application-level contract must not be violated otherwise things fall apart. There's no getting away from this (even in the REST case) - if you modify a schema we previously agreed on then you break me. I wouldn't call this a 404 nightmare though, this is just breaking a contract. The 404 nightmare arises where (just like on the Web) you have a bunch of externally addressable resources which you can happily go round modifying (you can because they're your resources) but in modifying them you break anyone that's bound to them
#
OK. But services that are beyond my control can evolve to break a contract that my application has bound to. Nothing profound in this, I just think it is similar to resources beyond my control dissapearing or changing in ways that the application does not anticipate.
#
Hey Nick. The difference is that services are generally long-lived, whereas obviously during the lifetime of a service its resource representations will change. So you cause more breakages more often if you advertise resources for consumers to bind to - nothing profound there either, it's encapsulation 101.
#
Regarding ProcessMessage and data requests, you say "That would be up to the "application-level" to figure out". Without getting into what you mean exactly (because I'm not sure), do you agree that you're no longer using a uniform ProcessMessage contract if you do that? Regarding 404, that's a feature, not a bug, since the only alternative is centralized registration of public identifiers. Yes, receiving a 404 is bad, but the solution from the URI publisher POV is easy; don't do anything that would require you to return one, i.e. maintain persistent URIs (which isn't as hard as you might think). Also, I think you might be confusing encapsulation and data-hiding; encapsulation - maintaining data and behaviour together - is a good thing, but data hiding - not exposing the internal state of an object - is IMO, very very bad for a large scale system. Well behaved Web clients will also bind to the identifier, not any particular representation, making them far less brittle than you appear to believe.
#
Mark, why do you say that the semantics of "ProcessMessage" are no longer used? They are used by the services that make up the applications to exchange messages (the documents). The semantics (for services) are clear: "receive and process". The application is composed from multiple services however. The application has to make sense of all the message exchanges that take place and reason about the semantics of the _contents_ of the messages being exchanged. This is not different from REST. In REST, all state representations are transferred according to the semantics of the application protocol operations, right? The application that uses those representations has to figure out what they mean for that application's specific purporses.
#
Savas, how does the page-request message identify the target of the page-content message? I ask because right now I'm typing behind a DHCP NAT and wonder how WS-TRANFER handles this.
#
Nick, Jim: Regarding ProcessMessage as a message dispatcher. The difference between a message dispatcher and REST is 1) HTTP has a standardized request body Method and Target (URI), and 2) HTTP has response, not void. Also, transport might be assumed in HTTP, but we could change the ProcessMessage signature to "Response ProcessMessage(method, uri, xmlNode)" and get similiar semantics.
#
Perhaps I don't understand what you mean by "application". I only see services, not applications. So when you say, regarding data requests, that "That would be up to the "application-level" to figure out", and also "The application is composed from multiple services", I'm confused. My statement about ProcessMessage semantics not being used was just to say that if you want to request data you need to do it as a transfer semantic, otherwise you're not using ProcessMessage. Said another way, representation semantics are orthogonal to transfer semantics.
#
Whoa, I'm losing track of who I'm responding to! Sorry Savas, I thought I was responding to Jim.
#
John: The very essence of ProcessMessage is that its "signature" is _not_ Response ProcessMessage(method, uri, xmlNode), though I guess I wouldn't object too much to thinking of it as Response ProcessMessage(xmlNode) for correlated message exchanges (though this would be at a higher level of abstraction than the basic ProcessMessage). I agree that you could make ProcessMessage REST-ish, but again that's a higher level of abstraction.
#
Jim: I didn't mean to imply that the signature of ProcessMessage includes those arguments. I was speculating that my signature is the smallest change to get a RESTful style.
#
Hey John, yes sorry I see that - I didn't mean to word my response to frame your comment that way! Your point is well made though, it shows that REST-ful semantics can be layered on top of ProcessMessage (and for that matter other styles that one happens to like).
#
Just to butt in on your conversation, as we've been discussing above, RESTful semantics (or any connector semantics, for that matter) cannot be layered on top of ProcessMessage while still respecting the ProcessMessage contract and reaping its benefits. Doing so is called "tunneling", i.e. basically using ProcessMessage as a transport layer abstraction. As-is, ProcessMessage is *already* partly RESTful in that it respects the uniform interface constraint. There's no need to layer stuff on top.
#
Mark: So ProcessMessage has uniform interface constraint, but what about common identification (URI) and common verbs (especially GET)? Couldn't there characteristics be layered on top?
#
Well, the uniform interface constraint is the constraint that requires "common verbs". But sure, to be fully RESTful ProcessMessage needs more constraints. I don't honestly know what Jim and Savas have in mind for identification, but I've seen them do stuff with both EPRs and URIs. That would be unRESTful because REST requires you pick a single identifying data element (which could be either EPRs *or* URIs). But no, there's no layering going on there, just extension. Extensions are "horizontal" (in the stack view of the world), while layering is vertical.
#
Indeed, I agree with Mark. Implementing any REST-like semantics on top of "ProcessMessage" would probably be a "tunneling" excercise but one that is possible.
#
As for data, remember... we have services, no data/resources. URIs could be used but they are used by the applications to refer to data/resources. They are not part of the architecture. The way services are addressed is architecture-indepedent. In WS, WS-Addressing would be used for message-based addressing.
#
Savas; actually, all services are resources, since every thing is a resource. And so you obviously need a way to identify them (even if they hold no state of their own). The architectural question for ProcessMessage is, does it require a single identifying data element for services? i.e. is it ProcessMessage-conformant to have a single system that uses incompatible identifier syntaxes? If so, then that wouldn't be RESTful.
#
Hey Mark. I could see ProcessMessage using WS-Addressing as its identification message, modulo the pointer-like bits. But to be honest that's an arbitrary choice.
#
Sure Jim, but I'm not talking about any particular identifying specification. I'm just asking if a ProcessMessage approach *requires* (aka constrains), for a particular system, a single service-identifying data element.
#
Mark, If you're asking "does a service have a uniquely identifiable address" then the answer is yes. A service has an address which is unique within its deployment domain - however it is _only_ the service which is addressable in ProcessMessage.
#
I wasn't asking that. Nevermind. 8-)
Author Name:
Email:
Author URL:
Comment:
Antispam:
Please type the following string (note that if the strings don't match, your comment will be lost... sorry!): 'AVLC'.
 
Recent entries

Recent comments

Feeds:
RSS 2.0 Atom