Guilhermesilveira's Blog

as random as it gets

Minimize coupling with REST processes

with 13 comments

While integrating systems, implementing access or processes is typically achieved through man ordered list of steps, where one expects specific results from the server.

Expecting specific results means coupling your client to a servers behavior, something that we want to minimize.

In REST clients, and in business process modeled following REST practices, we can reach lesser decoupling factors. Imagine the following system (among others) that buys products at amazon.com:


When there is a required item
And there is a basket
But didnt desire anything
Then desire this item as first item

When there is a required item
And there is a basket
Then desire this item

When it is a basket
And there are still products to buy
Then start again

When there is a payment
Then release payment information

The above code works and can be seen running in the last video from this post. In this Rest modelled process, several types of evolutions can happen on the server, without breaking the client:

1. After adding a product to the basket, if the server renders recommendations instead of your basket, the client still achieve its goal.

2. If some products are not found, the client is still able to pay for it.

3. If the server does not have the products, but links to another system in a affiliated program, we as clients will never notice it, and buy the products.

4. If we want to achieve the same goal in other systems that understand the same media type that we do, simply change the entry point..

Note the benefits from backward compatibility, forward compatibility and we are still capable to achieve our goals without knowing the existence of some changes on the protocol. We can even compare prices without changing one line of code, everything using well known media types as Atom. RDFa support can also be implemented.

This evolution power is not achieved in traditional process modelling, and several times, compatibility is left aside. This is something that REST and hypermedia brought us.

Mapping our process in a adaptable way using hypermedia was described in an article recently for the WWW2010 proceedings.

Now let’s imagine the traditional modelling:

  1. Search
  2. Add
  3. Search
  4. Add
  5. Pay

In a typical web services + business processing scenario, how would a server notify me to access another system without changing one line of code in my client? It would break compatibility.

If the server now supports a limited quantity of items in your basket, your client will also break, while the adaptable REST client adapts itself and buys what it is capable of.

If our produt or company uses those traditional paths and every change on the service implies in heavy change costs for clients, thats a hint that your project is too much coupled, and a REST client as mentioned might help.

Tradicional web services decouple a little bit more than traditional RPC, but still provide this amount of coupling that cost our companies more than they were expecting to pay.

The following presentation 6 minutes presentation shows how to avoid some of this coupling from your server.

The entire video cast on the 3rd part from Rest from scratch is here:

This code achieves its results using Restfulie 0.8.0, with many thanks to everyone who contributed maturing this release: Caue Guerra, Luis Cipriani, Éverton Ribeiro, George Guimarães, Paulo Ahagon, Fabio Akita, Fernando Meyer and others.

Thanks to all feedback from Mike Amundsen, Jim Webber and Ian Robinson.

Is your client api code already adapting itself to changes?

(update: changed some of the “Then” clauses from the dsl for easier spotting of document messages instead of commands)

Advertisements

Written by guilhermesilveira

May 27, 2010 at 4:40 pm

13 Responses

Subscribe to comments with RSS.

  1. Better than commands like “create a basket”, “add to basket”, “pay”, you should generate events like “desire basket”, “new item to be added to basket”, “ready to pay”. Let the hypermedia map the events to the commands. If you bake the commands into the code then you constrain what the hypermedia can do. e.g. with the event based approach, I can write an app that surveys what clients are interested in buying.

    Andrew Wahbe

    May 27, 2010 at 6:25 pm

  2. @andrew
    Thanks for the suggestion. Did you take a look at the internal code for this example? The code on the post is just the scenario, all the steps will follow resources that are actual resource names.
    Is that what you mean?

    guilhermesilveira

    May 27, 2010 at 6:32 pm

  3. I’m saying that you are only decoupling the client from the resource addresses. You do have a lot of constraints regarding what the resources represent and what actions can be taken on those resources. I believe REST can remove these constraints as well if implemented correctly — even when there is no human driving the client. Leverage the properties of events over commands as described here: http://bill-poole.blogspot.com/2008/04/avoid-command-messages.html but instead think about the “messages” being directed towards the hypermedia itself by the client. Hypermedia is interactive — it responds to messages from the client. The properties of those messages (constraints placed on client vs. server) have a strong effect on coupling.

    Andrew Wahbe

    May 27, 2010 at 9:07 pm

  4. Hello Andrew,

    I believe we are talking about the same thing. The four “commands”: “create a basket”, “add to basket”, “pay” and “start again” are not related to hypermedia at all.

    Just to be sure, the “desire basket” would be mapped to a POST to a basket relation? And the client would know that a basket relation means that there is a basket through the media type definition?
    Ready to pay would send an event message with the payment information? (or a callback?)

    i.e.:

    When there is a required item
    And there is a basket
    But didnt create a basket
    Then desire a basket

    When there is a required item
    And there is a basket
    Then desire this item

    When it is a basket
    And there are still products to buy
    Then start again

    When there is a payment
    Then ready to pay

    Thanks

    guilhermesilveira

    May 27, 2010 at 9:36 pm

  5. You are on the right track, but I think we differ on where the mapping occurs. I’m proposing that the hypermedia format itself has a notion of these events. A hypermedia page in this format would describe how to map the event to the appropriate HTTP requests. This gives the application more freedom in how it responds to the event. i.e. imagine if your notion of “steps” were actually described by the hypermedia instead of embedded in the client code — imagine the freedom that this would give apps. Now add the additional constraint (that you have given an example of above) that the steps are always events instead of commands so that there are no constraints on what has to happen when the hypermedia “step” is executed — more freedom, less coupling.

    Now this does bind the hypermedia format to the client event model — but HTML is bound to an event model — so are VoiceXML and CCXML. I think this is acceptable. We have conneg to allow the client to ask for a media type that not only portrays the data in the way that it wants, but also supports its event model.

    Andrew Wahbe

    May 27, 2010 at 10:05 pm

  6. I see… so if my hypermedia representation goes as

    “… if you desire an item, do this kind of request” and “if you desire to pay, follow this link with these information …”

    In a similar way that http would do with form+action+fields and giving semantic value to those forms?

    Regards

    guilhermesilveira

    May 27, 2010 at 10:18 pm

    • Yup. That’s pretty much it! Think about how this allows your client to interact with a much wider range of applications. For example, now it could interact with say an ordering system that keeps track of things that are desired so it can keep them in stock. You’ve eliminated all constraints on the application other than it support the uniform interface of HTTP + your media type.

      Andrew Wahbe

      May 27, 2010 at 10:24 pm

      • Hello Andrew!

        Is that a good client example for example binding only to the http uniform interface + my media type?

        1. GET /entry_point
        Accept: media_type

        2. Analyze the representation, search for a “form” on desiring an item, the form tells me to POST to /basket with some specific params

        3.POST /basket
        Content-type: specified-by-the-hypermedia-representation
        …content…

        4. Do it again for all other required items

        5. Analyze the representation and find out that there is a form for payment, which tells me to post to /payment, with some other fields

        6. POST /payment
        Content-type: …

        Something like that?

        guilhermesilveira

        May 27, 2010 at 10:45 pm

  7. I would be more tempted to split the client into an interpreter and platform — but that is because of my VoiceXML background — this is baked into the VoiceXML spec: http://www.w3.org/TR/voicexml20/#dml1.2.1

    So the interpreter would do something like this:

    1. GET /entry_point
    Accept: media_type

    2. Analyze the representation, and send a message down to the platform giving it a description of the current application state — or maybe some kind of command message — depends on the hypermedia format. Note here “message” could be a function call, some kind or IPC or whatever.

    3. The platform sends an event to the interpreter telling it an item is desired. The interpreter finds the “form” that handles desiring an item, the form tells it to POST to /basket with some specific params

    4.POST /basket
    Content-type: specified-by-the-hypermedia-representation
    …content…

    5. Do it again for all other required items

    6. The platform is happy with the current representation or is out of required items (who knows exactly why) and send a desire to pay event to the interpreter. The interpreter (based on the current document) finds the form that handles the payment desired event which tells it to post to /payment, with some other fields

    7. POST /payment
    Content-type: …

    I just think it’s a cleaner design — you could replace the interpreter with one for a new media type in the future etc.

    Andrew Wahbe

    May 28, 2010 at 2:21 am

  8. Wow… now that seems a perfect match.

    Restfulie is the interpreter while Restfulie::Mikyung allows you to write the platform code. The code you saw above is the platform one…

    Meanwhile the interpreter, which picks the correct “form” that handles desiring an item and formats the data accordingly is Restfulie and its media type handlers.

    In order to “teach” the interpreter how to deal with a new media type, you will implement a Media Type handler interface (with a couple of methods) – you can do that already.

    I suspected it was just my bad seleciton of words, but it does support what you have mentioned and those two concerns are already put appart from each other. Is that good?

    guilhermesilveira

    May 28, 2010 at 2:42 am

    • Yup! Actually, the interpreter/platform split that you already had really helped me to explain this whole event-driven client concept. I usually have a much harder time getting the idea across.

      Andrew Wahbe

      May 28, 2010 at 2:56 am

  9. […] Minimize coupling with REST processes […]

  10. […] Minimize coupling with REST processes – On reasons to decrease coupling in software systems using REST (+video!). Be sure to read the discussion in the comments of the post and the related thread on the REST discussion group. (by Guilherme Silveira) […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: