The future of web interaction
Tuesday, August 10th, 2004Adam Bosworth has summarized some great thoughts about the future of web interaction. His discussion of dealing with the offline problem is particularly inspiring.
Adam Bosworth has summarized some great thoughts about the future of web interaction. His discussion of dealing with the offline problem is particularly inspiring.
Mark Baker lays out a hint of things to come:
I still hope to respond to his earlier response to a question of mine, in what will likely end up being a mini treatise on state and state references. But that’ll have to wait.
Don’t wait too long, Mark. I’d really like to see that article!
My recap of the processThis concept seems to have been interpreted as a suggestion for how I think things should be. To the contrary, I wrote it as a tool to verify that I understood what Jim and Savas were saying, not in advocacy of the scenario described.
I did so because I think there might be an impedance mismatch in the ongoing conversation, and I wanted to be sure I understood. Mark is making inroads to clarification as he addresses Savas’ model of GET:
I think the comparison between HTTP request/response and “processMessage” is incorrect; the comparison should be between HTTP POST and “processMessage”.
I perceive at least three possible interpretations of processThis, and it might help if the parties involved clarify which they mean (or give other choices altogether):
processThis has an input and an output, both of which are unconstrained.processThis has an input which is unconstrained and a status output.processThis has an input which is unconstrained and has no output.I described (1) in my recap, and Jim Webber seemed to approve. I predict that Mark Baker sees (2), the equivalent to HTTP POST. And I suspect that Savas sees (3), by virtue of his Web Services model for GET.
Savas worries about embedding URIs in resource state:
My worry about this approach is that there is a coupling of an identifier (the URI), an interface (HTTP verbs), and the state on which these verbs operate. The approach may work for the web but as we attempt to build large-scale, distributed applications that do not involve the human factor, we may get complex networks of references between the states of resources containing references to other resources which, in turn, may lead to brittle applications.
A service that depends on being able to dereference a URL embedded in its state is indeed susceptible to failure if the authority serving the URL is unreliable. For example, step three of REST goes to Maui depends on being able to dereference the POSTed Reply-To, Status-To, and payment URLs. Is that an accurate summary of your concern, Savas?
It’s a good point and something that REST designs need to address if they depend on URLs. I would expect similar issues among aggregators of Web Services. How would you address the possibility that a Web Service might stop returning messages in a certain format or just suddenly cease to exist? I am hopeful that general principles to solve this problem in Web Services might yield clues to solving it in REST as well (or vice versa). Anyone care to offer a design pattern that addresses this?
URNs are not protocol specific, while URIs carry some protocol specific information. Also, we do not assume a coupling of the identified resource and the means by which the resource can be accessed.
URI, URN, URL–I try to be very careful to use URL only when I’m talking about a locator, and URI for everything else. I don’t typically use URN because we are increasingly using HTTP URIs as URNs. XML Namespaces and RDF, for example. I conjure up a URI by fiat:
http://www.geekaboo.net/names/garland/matt/
It doesn’t necessarily locate anything, it just identifies/names me or whatever else I choose for it to represent. A nice side effect is that it may locate something, but again, if I want reliability, I really shouldn’t depend on what it locates being anything in particular.
This usage is normative. The URI spec section 1.1 is clear that the “uniform” in URI (of which URN is a subset) means that URIs can be reused in contexts other than the protocol for which they were originally developed. Section 1.2 goes on to say that URIs can be both locators and names at the same time.
Savas’ advice to use URNs sounds good to me, but note that RFC 2396 permits me to use HTTP URIs (treating them as URNs) to the same effect. Whether I choose to couple that HTTP URI to the HTTP protocol is really just an implementation detail.
Mark Baker, how do you deal with these issues?
I’m a recent entrant to the blogging community, but I was getting so much out of one side of the conversation, I wondered how much better having both sides would be. I suppose I knew that someone would eventually respond to one of my entries, but I still managed to be surpised when it happened!
Jim Webber stumbled across my entry on uniform interface, and took issue with requiring an interface definition for a web service. His commentary there, and Savas’ recent piece, On the REST verbs vs. “processThis” discussion, are helping me understand their position.
Some key points that I missed early on:
processThis is an imaginary methodprocessThis method has the same semantics as POST does in REST, but can be bound to any underlying transport mechanismprocessThis by itself is constraintlessTo come back to concrete examples, let me offer the following:
I want to find some light reading for my upcoming vacation. I send a message to BookMonger, Inc. requesting books on Web Services. Let’s say that is a TopicSearch message. BookMonger returns me a TopicSearchResult message with some titles, descriptions, prices, etc. I form and submit a BookOrder to order Jim’s book “Developing Enterprise Web Services: An Architect’s Guide”. BookMonger sends back an OrderStatus indicating that the order is approved and that they expect it to ship within 24 hours. I’m impatient, and I send an OrderStatusInquiry every hour to check on my order. BookMonger obligingly responds with an OrderStatus each time. When the book (finally!) ships, they send me an unsolicited OrderStatus letting me know that the order has shipped.
There appear to be as few as two endpoints involved in this exchange. One for BookMonger, and one for me (to receive that unsolicited OrderStatus message). Perhaps the BookMonger endpoint is bound to HTTP, since BookMonger’s services seem to be mostly request/response. My endpoint is receive-response-only, and so might be bound to SMTP.
Any time a message is posted to an endpoint, the endpoint recognizes the message and handles it. In this way, the imaginary processMessage verb is invoked.
Not every endpoint recognizes every message, though. If I posted my BookOrder message to ToasterMonger, they wouldn’t know what to do with it and would presumably reject my message. And so enter WSDL. WSDL seems capable of making it clear that ToasterMonger doesn’t accept book orders; ToasterMonger wouldn’t define a BookOrder message.
BookOrderShredders, on the other hand, could conceivably define a BookOrder, but surely the results of posting a message to their endpoint are different! So I potentially have to distinguish between the outcomes of posting the same message to two different web services. I’m not aware that WSDL provides the means for making this distinction. Savas claims that
There are no semantics attached to the imaginary ?receiveMessage?
They must be attached to something, though, so I suppose that it’s the combination of the endpoint and the message.
Thanks for putting your thoughts out there, guys. Is this an accurate description of the processThis concept? Jump in and clarify it for me.
A couple of ideas I don’t want to lose regarding how to POST reliably in HTTP :
Mark Nottingham and Paul Prescod recommend similar solutions. The server gives out unique URIs for handling POSTs. These URIs accept only a single POST, preventing multiple POSTs from causing duplication.
Mark suggests that a second POST respond with status information:
If the server receives more than one POST to any particular ‘action’ link, it should generate a message saying “This order has already been submitted,” perhaps along with a summary of the order and its status.
Paul takes a different approach:
The response of subsequent POSTs should be the same as if there had been only one POST so that the client can get the correct response even if there is a network outage in the middle of the first response.
John Beatty has a nice follow-up article in which he points out that this kind of behavior might not be RESTful. The server has to remember ephemeral application state (the request identifier) from a previous request in order to service the current request.
Mark Baker weighs in:
There are actually ways of doing id generation on the server and still having it be stateful [I think Mark means to say “stateless” here. –mgarland] though; generate a URI on the server, and pass it to the client with the intent that the data be PUT to that URI. That way you get to use the idempotence of PUT, though at the cost of another round trip. But that could be amortized by sending a batch of URIs which can be reused as the client sees fit.
This puts the state back on the client in the form of a URI. Presumably, the server can extract enough state from the URI to serve the resource.
I toyed with the thought of using GET to find the unique URI. Then POST to the unique URI creates the resource at the URI, at-most-once, and must occur before PUT, GET, or DELETE to that URI make sense.
But I suspect that doing so may lead to race conditions that require the client to two-step with (409) Conflict, and it might also violate the definition of POST:
accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line
I’d love to hear informed opinions on this. For now, I’m POSTing to get the unique URI and PUTing the desired state.
Jim Webber suggests that a single verb is a sufficent “uniform interface”, and wonders why more are necessary. Mark Baker responds that POST is what Jim is describing, but makes a good case for including GET. And to Mark’s comment
That’s really good to hear you say that Web services have uniform semantics. But it’s impossible for them to be more uniform than REST, because REST prescribes uniform interface semantics by definition. - Mark Baker
I have to admit I don’t get this. What does it mean? - Bill de hÓra
Bill de hÓra offers some good guidance on service model evolution:
The core problem of component and service architectures is easy to express: how do I change a published interface without breaking the callers?
I’ve summarized the major points and made some additional notes from a .NET background (with an eye toward REST).
Mark Baker and Savas are discussing service description. Mark suggests that its better for the interface and description to be dynamically negotiated. Is this workable in practice, or just ivory tower? (more…)