On Mon, 2006-12-11 at 15:53, Steve Jones wrote: > On 11/12/06, Andrew S. Townley <[EMAIL PROTECTED]> wrote: > > On Mon, 2006-12-11 at 13:35, Steve Jones wrote: > > > On 11/12/06, Andrew S. Townley <[EMAIL PROTECTED]> wrote: > > > > > > I think I finally get the disconnect here. Steve's trying to put the > > > > client in control and REST (as Jan explains pretty well) is about > > > > putting the service in control. I think this is important, and I also > > > > think this is why SOA is better than what we've had before. > > > > > > Not quite, the Service is in control of what it does has always been > > > my view. But the value of the service is only realised when it is > > > invoked by a consumer. Hence the reason why you should design > > > interfaces with clients, not services, in mind. > > > > > http://service-architecture.blogspot.com/2006/07/consumers-view-of-service-description.html > > > > Amusing post (I laughed), but it isn't what I'm talking about. > > > > Since we've mentioned Amazon, let's look at this scenario and see if I > > can explain what I mean. If you were to describe Amazon in 2 min as a > > service interface, you might get something like: > > > > Bookseller > > - findBooks > > - findBooksMatching > > - viewBook > > - addToCart > > - placeOrder > > > > There's more, but this is enough. The way I understand a REST approach > > to providing this service you'd have something like this (data-types > > aside; as I mentioned, that's a different discussion): > > > So its taken you 9 lines to describe the service interface...
Not really, this is the equivalent of the WSDL definition. As you keep asking, where is the definition of the "order book" business process that tells me when to invoke each of those methods? I could just guess, or I could try them and handle exceptions, the equivalent of the IllegalStateException and MethodNotAllowed, but don't you see why those exceptions need to exist? They need to exist because each of these methods is available to all clients all the time. What if depending on where you were in the "order book business process" the remote interface could change? Wouldn't that eliminate you as a client from needing to know about IllegalStateException or MethodNotAllowed? If your client, sitting in the start state only had a single operation, wouldn't that be simpler to deal with? (Yes, HTTP has something like this, but it's handled at a lower level and your application just sees an error.) > > > > Step 1: GET amazon.com > > > > This returns an HTTP 200 response code and an HTML+Form response with a > > bunch of links. > > > > What you can do: > > - follow a link to view an item > > - follow a link to view items within a pre-selected category > > - enter search times to find items that match your search criteria > > - follow a link to view the contents of your cart > > - follow a link to view your account settings > > > > Now, I'll admit there's some processing involved to determine that the > > view and item link and the contents of cart links are different, but if > > you follow them (do a GET), you should "recognize" the representations > > (more on this in a minute). > > > > Step 2: follow a link to view an item (GET the URI) > > > > This (best case) returns an HTTP 200 status code an another HTML+Form > > response that happens to be something that you recognize (or maybe it's > > an XForms XML document whose data model's root element corresponds to > > the AmazonItem schema and it contains references to submit actions for > > 'add to cart'. I'm not sure if this is right, but why not?) > > > > What you can do here is: > > > > - follow a link to view an item > > - follow a link to view items within a pre-selected category > > - enter search times to find items that match your search criteria > > - follow a link to view the contents of your cart > > - follow a link to view your account settings > > - add the item to the cart with the submission of a form operation > > - complete the order with a machine equivalent of 'one-click order' > > based on knowing your identity. > > And quite a bit more to describe it in REST. Now you can argue that > you've allowed more flexibility in the REST interface, but you've also > got a lot more complexity. That's because I was trying to give you some additional context to understand what I was saying. To use the 9 liner as a starting point, in step 0 your interface would be: RemoteService - get Then at step 1, your interface would be: ProductCatalog - findBook [fixing a typo in the original email] - findBooksMatching - viewBook At step 2, your interfaces would be: ProductCatalog - findBook - findBooksMatching - viewBook ProductItem - addToCart Taking this a bit further, you might get after adding the item: ProductCatalog (...) ShoppingCart - checkout etc. If you're with me now, then this looks like normal OO, right? However... what if each of those "interfaces" was really just an XML document identified by both a MIME type and optionally by an XML schema (if you had a rich enough library of MIME types, you wouldn't need the schema, because the MIME type would be effectively the same as the namespace URI on the root node of the document, but from a maintenance point of view, you could argue this is why there aren't specific MIME types for the various versions of HTML--XHTML is a different beast). Then, what about those operations. What if you could find each of them based on an XPath expression like (I'm making this up, btw) //xforms:submission/*? If your client understood how to make an XForms submission and understood how to associate data values with the instance documents expected in the XForms entities, your client can pick and choose the ones it understands. Instead of understanding an OO type of interface, what you're dealing with is the following: 1) do I understand/recognize what kind of thing I have? 2) do I understand/recognize any of these business-level "actions" present in this thing I have? Now that I think about it, it's almost exactly like doing a respondsTo check on an Object in Objective C. If you understand the operation within the context that you have, you can perform the operation--even if it's in another context (interface), but to allow this the semantics of that operation must never vary from context to context. The application semantics must still be shared to provide this recognition, and yes, it is a richer problem than HTML+Forms, even when dealing with the above example, but it's more like having a collection of fixed-purpose, Flyweight objects lying around that you can assemble based on the content that you're trying to process rather than trying to create a fixed, therefore inflexible, higher-level construct *in code*. Your applications interface is defined in terms of the capabilities rather than an enclosing interface. In HTML+Forms, those capabilities are: * HTML presentation * FORM processing and submission * Hyperlink traversal and the latter two all work based on basic use of HTTP. That basic idea still exists in the application, and there will need to be some code or human somewhere to make sense of what all of those Flyweights are telling you, but while they collectively might make up a view of the service's business interface at a fixed point in time, individually, they do not. Therefore, the composition and function of Flyweights may vary, but if a *particular* Flyweight is present or is used, it means something specific. This is also why the Reach XML schemas are so modularized, btw. An address is always an address and has some fixed information, but what that address *means* in the context of a larger business document is defined by that document. If you change the structure of the address, it doesn't change the meaning of the document, nor should it cause anything other than the part of the system that understands addresses to change. If you've bound this into a data model that says PO and Invoice are monolithic documents and generated code as such from your WSDL, then you've a major compatibility problem. > > This is the answer to your earlier question about how do you represent > > compliance steps or whatever needs to happen during the interaction. > > It's all about what you expose to the client as available options *at > > each step of the process* that directs the client to "do the right > > thing" or at least "do *one* of the right things" for a given step in > > the overall interaction. > > > > I could go on with more steps, but it wouldn't prove much. The thing is > > that the available operations to the client at any time t varies > > depending on the client's current position within the application state > > machine provided by the service. State traversal can only take place > > using one of the HTTP operations, but the implications of those state > > transitions come from the interpretation of the hypermedia document > > exposed to the client at time t. > > > > At time t+1, the options could be different (maybe you can have your > > items beamed to your home rather than shipped via UPS). If you > > understand what "beam my items" means, great. If not, you still pick > > the "ship it" option of the choices the way you did at time t, and > > everything still works. The people whose client understands Star Trek > > transporters just get their items a little bit quicker. :) > > > > This type of dynamic, service-controlled interaction is what I do think > > isn't part of any WS-* system I've ever seen (or CORBA, or EJB or any > > programming API on the planet). It's still testable because you are > > testing what you can detect, interpret and how your client can prepare > > the data necessary for POST or PUT operations, but you're agreeing and > > testing capabilities and semantics rather than invocation and you don't > > have to know anything more about when to invoke an action other than > > "you can only do it if you see it in front of you". > > So you are saying that this is simpler than having a schema change on > the "placeOrderRequest" which includes the new shipping option? > > I'm not seeing that. I'm not sure if the above helped or made it worse. Also, I'm not entirely sure if the rest of the people who know more about it would even call it correct... To me it's simpler because you have a new application capability which, through not binding it tightly to a fixed interface description, doesn't require you to touch any of your existing client implementations. It's like having mustUnderstand=0, but most people I've met never really think about the advantages of this over using mustUnderstand=1. The work we did (and the subsequent hair-pulling on my part that ensued) around the extension point processing model to achieve forward/backward compatibility in the Reach schemas made me appreciate the power of *not* restricting the schema to a fixed description. > Also the arugment here appears to be for continuous process rather > than more dynamic goal oriented things, I might not see something in > front of me but why can't I just go somewhere else to do it? This > sounds like for REST you should always do a GET before a POST or PUT, > rather than caching the last GET as that might not be valid anymore. That's exactly right, because you're not supposed to know about *how* you can do something with a particular service until you interact with it (unless it's documented, and therefore you're back to all of the change control you have in a more traditional model). The *what* of your service is most certainly agreed upon in advance, however. If the extent of your documentation says: * These are the entity representations and semantics for our business domain, * These are how they are associated to each other, and * These are the way you identify and execute this fixed list of actions we support, then all your client needs to be told is: GET <my service base URI> and follow the signs. This means that on Monday (you wouldn't really do this, but it's all I could think of), your service may return representations with forms targeting POSTs to <baseURI>/monday, on Tuesday, it may return representations targeting POSTs to <baseURI>/tuesday, and so on. As a client, you don't need to know or care when those URI targets change, you just "do what you're told" and POST to the URI present in the hypermedia representation you were given (this is what opacity means to me, btw). Where do you draw the line between continuous process and dynamic, goal-oriented things? Isn't that all about perspective, just like the "what is a service?" question? To me it's atomic, to you, a participant in it, it's a collection of a bunch of other atomic operations, as far down the fractal decomposition as you care to go. > > Does this make sense? I truly see there's a difference here, but it > > might be difficult to see if you only focus on the words or the > > individual parts. The above example is about what I meant about "the > > server is in control of the interaction". > > And I'm with that as a theory, but I don't see how REST is better than > WS at this stage. Like I said I've always said that what is behind > the service stays behind the service. But saying that process can > _never_ be fixed is a bit odd when you look at things like invoicing > and receipting which haven't changed in 100 years or so, why would it > be bad to save time by hard-wiring that? You're right, those high-level business processes are well defined, core parts of the business. This is part of the points I try and make when I'm talking to people about "business agility" and building systems that can adapt to change within the business. Focus on designing in the articulation points that you know need to be there. The core business of the enterprise isn't going to change as quickly as the demand for a particular service or even the services being offered (e.g. telco environments). I'm saying that those interactions, defined in the abstract sense, are something that you can design, model and automate, but as soon as you tie that abstract processing model to a particular data encoding or transport, you've lost your ability to allow the system to evolve gracefully. This is where the 70% of the total lifecycle costs that Boehm talks about comes in. The system shouldn't require a massive upgrade when someone decides they want to have 5 lines of address vs. 4 because they've started doing business in Europe. It's still purchasing, it's still an invoice, and the same processes take place. This is why I think XML is *good* for stuff like this, but it is not good if the software around the XML is tightly bound to what *all* the data looks like today instead of what the *important* data really says. The only approach to distributed systems I've seen which can potentially achieve this is one that isn't based on strongly typed representations of the details of the remote systems requirements today. This is why I think REST is so important. > > > > With REST, this isn't the case. The server is in control of the > > > > interaction, not the client. The client is an active participant and > > > > always has an option of stopping the conversation at any point, but > > the > > > > server is responsible for maintaining the application state internally > > > > (but it may push the storage of that state information out to the > > client > > > > and not manage it itself). > > > > > > Not sure how this is different to any standard system of the last 30 > > > years. A database could make the same claim. I don't think it can. You can issue any of CREATE, UPDATE, DELETE or INSERT in any order at any time, because it's still an API. Yes the vocabulary is fixed, but what you don't have is a context-specific view of the available operations at any point in time. > > > > > > > > REST is more like eating a set dinner rather than ordering off a menu. > > > > Traditional programming is always about ordering al a carte. This is > > > > part of the shift in perspective that's required to successfully build > > > > systems using the REST architectural style. > > > > > > Again this has nothing to do with REST, ERPs are about the set dinner > > > as well, and I've always argued that dictate is the best way to get > > > stuff done. Most projects I've ever done have dicated the format and > > > the approach, this works. REST isn't inventing anything new here. > > > > But they're still APIs that you need to understand how to choreograph to > > achieve what you want to do. > > Which is the same as REST, REST doesn't stop me having to understand > what I want to achieve, nor does it stop me having to understand what > the server enables me to do in order to achieve my goal. > > I'm clearly missing something, but I can't see what it is. > > > > > > > > > > > On the other hand, Steve also has some good points about the agreement > > > > of data models between parties. Part of why the Web works is because > > > > HTTP, Forms and HTML are everywhere, but to encode something outside > > of > > > > that space requires additional agreements. There are ways to do this, > > > > e.g. UBL, but they aren't as ubiquitous as HTML+Forms. Atom will > > help, > > > > but only partially. However, the inversion of control aspect of REST > > > > and the definition of the messages exchanged are two separate issues. > > > > > > The "inversion of control" as you call it is not news, I've always > > > argued on standardisation and dictat for interfaces and on the drive > > > towards vanilla except where it actually differentiates. So REST (for > > > me) doesn't offer anything new. > > > > No, the concept isn't new, but the way in which it manifests itself > > seems to me to be. > > But not for me, nor I'd say for people who put in ERP solutions, go > and ask SAP what the best way to do things is.. the answer will be > "our way". But here you're unfortunately not getting what I'm trying to say about the importance of the context in determining when you can do something. Yes ERP vendors can be 800# gorillas and say this is the way that it is, but that just means that you have to wade through forests-worth of documentation to figure out how to discard all of the APIs that aren't relevant to what it is you're trying to do. In a properly designed REST system, your choices are limited automatically by where you start. What you're saying isn't the same as what I'm saying. > > > > > The definition of the exchange should be done from the perspective of > > > the "many" however rather than the "few", if you have a server centric > > > interface it will be less usable than one that hides the nasty bits of > > > the server from the clients. This doesn't mean that clients dicate > > > anything, it just means that you have a strong design. My question > > > with REST is around the exchange as you say, and I'm struggling to see > > > how REST is an advance over old ways, it sounds too much like old > > > "techy knows best" approaches that I've seen on projects over the > > > years. > > > > I tried to explain this above. Maybe I still haven't made it clear, but > > it's at least clearer to me right now than it was last week. > > The thing is I think I get the mechanism of REST now, I just don't see > why I'd want to do it, and I _really_ don't see how its simpler to use > for developers and support folks. I don't really think it's simpler for developers--precisely because it means that you can't automatically generate code and hard-code the hell out of the problem you're trying to solve to make it "easy to implement" and get it delivered "on time". But I do think it makes for systems that are simpler to maintain over time with less cost. I do think it can be simpler for the support folks, but I don't have any good examples at the minute... > > > > I can keep trying though if you like... ;) > > Hey its better than working.... Doesn't pay the bills, though! :) (remember that I'm now responsible for sales, marketing and service delivery) This is certainly coming out of my learning and development budget. At least it's a long-term investment. ast -- Andrew S. Townley <[EMAIL PROTECTED]> http://atownley.org
