Loading ...
Sorry, an error occurred while loading the content.

Re: [rest-discuss] Why HATEOAS?

Expand Messages
  • Kevin Duffey
    The last point really hits home for me. If I understand it correctly, as a client consuming an API that adheres to what Craig is saying, I can, for example
    Message 1 of 27 , Mar 31, 2009
    • 0 Attachment
      The last point really hits home for me. If I understand it correctly, as a client consuming an API that adheres to what Craig is saying, I can, for example rely on the fact that a given URI might be changed by the server, say due to a bug fix or a new version deployed, but mean while my client still works without breaking. I would guess the server implementation would document this fact, especially in the case of a newer version deployed that may change the URI, but I particularly find this beneficial to clients for exactly the reason Craig gives, less worry about my client breaking due to a server URI change. As long as the expected functionality and response remains the same we're good.

      I never considered the 2nd point. Very interesting indeed. Craig did help me with something like this... pagination. In a search engine app for example, a consumer could get a 1 - 100, 101 - 200, etc back. By returning the proper URI to get the next series, and/or previous series of results, I myself do not need to figure out the values to send in the request.. I can simply pluck the URI the server returns for the next/previous, and use it with assurance.



      From: Craig McClanahan <craigmcc@...>
      To: Solomon Duskis <sduskis@...>
      Cc: Rest List <rest-discuss@yahoogroups.com>
      Sent: Tuesday, March 31, 2009 5:59:03 PM
      Subject: Re: [rest-discuss] Why HATEOAS?

      On Tue, Mar 31, 2009 at 5:01 PM, Solomon Duskis <sduskis@gmail. com> wrote:

      > [snip]
      > Assuming that the practical barriers of entry are removed, what practical
      > benefits will we see?
      >

      I know exactly where you are coming from with these questions ... I
      felt the same way until recently. I've designed several REST APIs
      over the last couple of years, but up until the most recent one, I
      designed and documented them in the "typical" way, describing the URI
      structure of the application and letting the client figure out what to
      send when. My most recent effort is contributing to the design of the
      REST architecture for the Sun Cloud API[1] to control virtual
      machines and so on. In addition, I'm very focused on writing client
      language bindings for this API in multiple languages (Ruby, Python,
      Java) ... so I get a first hand feel for programming to this API at a
      very low level.

      We started from the presumption that the service would publish only
      *one* well-known URI (returning a "cloud" representation containing
      representations for, and/or URI links to representations for, all the
      cloud resources that are accessible to the calling user). Every other
      URI in the entire system (including all those that do state changes)
      are discovered by examining these representations. Even in the early
      days, I can see some significant, practical, short term benefits we
      have gained from taking this approach:

      * REDUCED CLIENT CODING ERRORS. Looking back at all the REST client
      side interfaces
      that I, or people I work with, have built, about 90% of the bugs
      have been in the construction
      of the right URIs for the server. Typical mistakes are leaving out
      path segments, getting them
      in the wrong order, or forgetting to URL encode things. All this
      goes away when the server
      hands you exactly the right URI to use for every circumstance.

      * REDUCED INVALID STATE TRANSITION CALLS. When the client decides
      which URI to call and
      when, they run the risk of attempting to request state transitions
      that are not valid for the current
      state of the server side resource. An example from my problem
      domain ... it's not allowed to
      "start" a virtual machine (VM) until you have "deployed" it. The
      server knows about URIs to
      initiate each of the state changes (via a POST), but the
      representation of the VM lists only the
      URIs for state transitions that are valid from the current state.
      This makes it extremely easy
      for the client to understand that trying to start a VM that hasn't
      been deployed yet is not legal,
      because there will be no corresponding URI in the VM representation.

      * FINE GRAINED EVOLUTION WITHOUT (NECESSARILY) BREAKING OLD CLIENTS.
      At any given time, the client of any REST API is going to be
      programmed with *some* assumptions
      about what the system can do. But, if you document a restriction to
      "pay attention to only those
      aspects of the representation that you know about", plus a server
      side discipline to add things later
      that don't disrupt previous behavior, you can evolve APIs fairly
      quickly without breaking all clients,
      or having to support multiple versions of the API simultaneously on
      your server. You don't have to
      wait years for serendipity benefits :-). Especially compared to
      something like SOAP where the
      syntax of your representations is versioned (in the WSDL), so you
      have to mess with the clients
      on every single change.

      Having drunk the HATEOAS koolaid now, I would have a really hard time
      going back :-).

      Craig McClanahan

      [1] http://kenai. com/projects/ suncloudapis/ pages/Home


    • amsmota@gmail.com
      Excellent explanation, you should publish that somewhere for easy reference. I think this will give me the final argument to convince my boss to give me the
      Message 2 of 27 , Apr 1, 2009
      • 0 Attachment
        Excellent explanation, you should publish that somewhere for easy reference. I think this will give me the final argument to convince my boss to give me the extra-time i need to fully implement hateoas in our infrastructure...

        On Apr 1, 2009 1:59am, Craig McClanahan <craigmcc@...> wrote:
        >
        >
        >
        >
        >
        >
        >
        >
        >
        > On Tue, Mar 31, 2009 at 5:01 PM, Solomon Duskis sduskis@...> wrote:
        >
        >
        >
        > > [snip]
        >
        > > Assuming that the practical barriers of entry are removed, what practical
        >
        > > benefits will we see?
        >
        > >
        >
        >
        >
        > I know exactly where you are coming from with these questions ... I
        >
        > felt the same way until recently. I've designed several REST APIs
        >
        > over the last couple of years, but up until the most recent one, I
        >
        > designed and documented them in the "typical" way, describing the URI
        >
        > structure of the application and letting the client figure out what to
        >
        > send when. My most recent effort is contributing to the design of the
        >
        > REST architecture for the Sun Cloud API[1] to control virtual
        >
        > machines and so on. In addition, I'm very focused on writing client
        >
        > language bindings for this API in multiple languages (Ruby, Python,
        >
        > Java) ... so I get a first hand feel for programming to this API at a
        >
        > very low level.
        >
        >
        >
        > We started from the presumption that the service would publish only
        >
        > *one* well-known URI (returning a "cloud" representation containing
        >
        > representations for, and/or URI links to representations for, all the
        >
        > cloud resources that are accessible to the calling user). Every other
        >
        > URI in the entire system (including all those that do state changes)
        >
        > are discovered by examining these representations. Even in the early
        >
        > days, I can see some significant, practical, short term benefits we
        >
        > have gained from taking this approach:
        >
        >
        >
        > * REDUCED CLIENT CODING ERRORS. Looking back at all the REST client
        >
        > side interfaces
        >
        > that I, or people I work with, have built, about 90% of the bugs
        >
        > have been in the construction
        >
        > of the right URIs for the server. Typical mistakes are leaving out
        >
        > path segments, getting them
        >
        > in the wrong order, or forgetting to URL encode things. All this
        >
        > goes away when the server
        >
        > hands you exactly the right URI to use for every circumstance.
        >
        >
        >
        > * REDUCED INVALID STATE TRANSITION CALLS. When the client decides
        >
        > which URI to call and
        >
        > when, they run the risk of attempting to request state transitions
        >
        > that are not valid for the current
        >
        > state of the server side resource. An example from my problem
        >
        > domain ... it's not allowed to
        >
        > "start" a virtual machine (VM) until you have "deployed" it. The
        >
        > server knows about URIs to
        >
        > initiate each of the state changes (via a POST), but the
        >
        > representation of the VM lists only the
        >
        > URIs for state transitions that are valid from the current state.
        >
        > This makes it extremely easy
        >
        > for the client to understand that trying to start a VM that hasn't
        >
        > been deployed yet is not legal,
        >
        > because there will be no corresponding URI in the VM representation.
        >
        >
        >
        > * FINE GRAINED EVOLUTION WITHOUT (NECESSARILY) BREAKING OLD CLIENTS.
        >
        > At any given time, the client of any REST API is going to be
        >
        > programmed with *some* assumptions
        >
        > about what the system can do. But, if you document a restriction to
        >
        > "pay attention to only those
        >
        > aspects of the representation that you know about", plus a server
        >
        > side discipline to add things later
        >
        > that don't disrupt previous behavior, you can evolve APIs fairly
        >
        > quickly without breaking all clients,
        >
        > or having to support multiple versions of the API simultaneously on
        >
        > your server. You don't have to
        >
        > wait years for serendipity benefits :-). Especially compared to
        >
        > something like SOAP where the
        >
        > syntax of your representations is versioned (in the WSDL), so you
        >
        > have to mess with the clients
        >
        > on every single change.
        >
        >
        >
        > Having drunk the HATEOAS koolaid now, I would have a really hard time
        >
        > going back :-).
        >
        >
        >
        > Craig McClanahan
        >
        >
        >
        > [1] http://kenai.com/projects/suncloudapis/pages/Home
        >
        >
        >
        >
        >
        >
        >
        >
        >
        >
        >
        >
        >
      • Andrew S. Townley
        ... [snip] ... Hi Chris, This was a great post. I m looking at doing something similar for an application as well, but, having looked at the API for the Sun
        Message 3 of 27 , Apr 1, 2009
        • 0 Attachment
          On Tue, 2009-03-31 at 17:59 -0700, Craig McClanahan wrote:
          > On Tue, Mar 31, 2009 at 5:01 PM, Solomon Duskis <sduskis@...>
          > wrote:
          >
          > > [snip]
          > > Assuming that the practical barriers of entry are removed, what
          > practical
          > > benefits will we see?
          > >
          >
          > I know exactly where you are coming from with these questions ...

          [snip]

          Key advantages:

          > * REDUCED CLIENT CODING ERRORS.
          >
          > * REDUCED INVALID STATE TRANSITION CALLS.
          >
          > * FINE GRAINED EVOLUTION WITHOUT (NECESSARILY) BREAKING OLD CLIENTS.

          > Having drunk the HATEOAS koolaid now, I would have a really hard time
          > going back :-).

          Hi Chris,

          This was a great post. I'm looking at doing something similar for an
          application as well, but, having looked at the API for the Sun Cloud, I
          was planning on taking it a bit further.

          One thing that I see missing is "full disclosure" of the operations
          (verbs) to be used as well as differentiation between actions vs.
          information.

          Don't get me wrong, I think the API you have is pretty good! :)

          However, the only way that I could think of doing what I'm talking about
          was to define some kind of envelope, or at least a series of elements
          that were influenced by or imported directly the XHTML forms (and/or
          possibly XForms) elements to identify what actions were possible for a
          given resource. That way, you'd have the full HATEOAS in the message
          and the clients wouldn't have to know anything except how to interpret
          the markup. I guess I should also say that I'm looking at XML
          representations here rather than JSON.

          I was planning on posting some thoughts on this anyway, but the timing
          of this post was too good to pass up.

          What I was thinking was something like:

          <ActionEnvelope>
          <Header>
          <ActionList>
          <Action id="action1" href="uri" method="POST">Human readable description of the action here</Action>
          <Action id="delete" href="uri" method="DELETE">Delete this resource</Action>
          ...
          </ActionList>
          </Header>
          <Body>
          <!-- any content can go here, and client processing will be based on
          either the elements or the namespace URI(s) used in the root child
          element -->
          </Body>
          </ActionEnvelope>

          Now, before everyone gets all fussy and says it's too much like SOAP, it
          truly isn't. The only thing in common is that it uses an envelope.

          The other thing to note is that the total transitions available to the
          client are the sum of any in-lined (like FORM submissions, regular
          hyperlink traversal, etc.) and then any of the other, "meta" actions
          possible for the system as a whole defined in the envelope's header.

          I went through several iterations of putting them in in the "real"
          resource vs. in the header, but this is where I'm thinking at the
          moment, because it allows you to easily process the resource for both
          human and machine interaction (the action list becomes a menu, for
          example, if the ultimate user agent wants (X)HTML -- this can be
          accomplished a number of different ways).

          I was wondering if you guys went through this line of thinking with your
          API design and discarded it, or if it was deemed either unnecessary or
          too complicated.

          Of course, with this approach your automated user agent still needs to
          understand the semantics of the action id's, but this would be published
          as part of the API specification, separate from the specification for
          the underlying content schema(s), and the inputs required would be fully
          supplied after making the request defined by the action.

          This isn't terribly efficient, because an editing operation for the
          resource might look like:

          Step 1) Get the resource URI

          Step 2) Process the resource XML, recording the actions

          Step 3) If an action with ID "edit" exists in the header, but no form
          exists in the body, make request for "edit" resource

          Step 4) Process the resource XML looking for "resource editing" mark-up
          (defined by the API spec, probably a normal FORM in the envelope body)

          Step 5) Supply available form values to be changed (also prevents
          changing of read-only resource properties)

          Step 6) Submit FORM

          Step 7) Process HTTP server response

          Granted, this certainly not as efficient as:

          PUT /vms/33333
          Host: example.com
          Authorization: Basic xxxxxxxxxxxxxxxxxxx
          Accept: application/vnd.com.sun.cloud.VM+json
          Content-Length: nnn
          Content-Type: application/vnd.com.sun.cloud.VM+json
          X-Cloud-Client-Specification-Version: 0.1

          {
          "description" : "This is the new description"
          }

          But how does the user agent know it can do this from the original
          resource?

          HTTP/1.1 200 OK
          Content-Type: application/vnd.com.sun.cloud.VM+json
          Content-Length: nnn

          {
          "name" : "web01",
          "uri" : "http://example.com/vms/33333"
          "run_status" : "RUNNING",
          "model_status" : "DEPLOYED",
          "description" : "This is the old description"
          ...
          "back_up" : "http://example.com/back-up?vm=33333"
          "attach" : "http://example.com/attach?vm=33333",
          "detach" : "http://example.com/detach-ip?vm=33333",
          ...
          }

          I realize the propsal above isn't perfect either, but it's really still
          in the embryonic phases at the moment. However, I plan on actually
          working through much of the detail over the next few months, so any
          feedback (good, bad or otherwise) is welcome.

          The Sun Cloud API is one of the more interesting ones that I've seen
          recently, and I'm sure there's lots to learn from it.

          Nice work.

          ast
          --
          Andrew S. Townley <ast@...>
          http://atownley.org
        • Stefan Tilkov
          Excellent points. I d like to add that following links instead of constructing URIs also enables an evolutionary change of distribution of resources across
          Message 4 of 27 , Apr 1, 2009
          • 0 Attachment
            Excellent points. I'd like to add that following links instead of
            constructing URIs also enables an evolutionary change of distribution
            of resources across multiple servers or domains – something I've found
            extremely valuable in scaling a system from deployment to various
            (stages of) production environments.

            Stefan

            On 01.04.2009, at 02:59, Craig McClanahan wrote:

            > On Tue, Mar 31, 2009 at 5:01 PM, Solomon Duskis <sduskis@...>
            > wrote:
            >
            > > [snip]
            > > Assuming that the practical barriers of entry are removed, what
            > practical
            > > benefits will we see?
            > >
            >
            > I know exactly where you are coming from with these questions ... I
            > felt the same way until recently. I've designed several REST APIs
            > over the last couple of years, but up until the most recent one, I
            > designed and documented them in the "typical" way, describing the URI
            > structure of the application and letting the client figure out what to
            > send when. My most recent effort is contributing to the design of the
            > REST architecture for the Sun Cloud API[1] to control virtual
            > machines and so on. In addition, I'm very focused on writing client
            > language bindings for this API in multiple languages (Ruby, Python,
            > Java) ... so I get a first hand feel for programming to this API at a
            > very low level.
            >
            > We started from the presumption that the service would publish only
            > *one* well-known URI (returning a "cloud" representation containing
            > representations for, and/or URI links to representations for, all the
            > cloud resources that are accessible to the calling user). Every other
            > URI in the entire system (including all those that do state changes)
            > are discovered by examining these representations. Even in the early
            > days, I can see some significant, practical, short term benefits we
            > have gained from taking this approach:
            >
            > * REDUCED CLIENT CODING ERRORS. Looking back at all the REST client
            > side interfaces
            > that I, or people I work with, have built, about 90% of the bugs
            > have been in the construction
            > of the right URIs for the server. Typical mistakes are leaving out
            > path segments, getting them
            > in the wrong order, or forgetting to URL encode things. All this
            > goes away when the server
            > hands you exactly the right URI to use for every circumstance.
            >
            > * REDUCED INVALID STATE TRANSITION CALLS. When the client decides
            > which URI to call and
            > when, they run the risk of attempting to request state transitions
            > that are not valid for the current
            > state of the server side resource. An example from my problem
            > domain ... it's not allowed to
            > "start" a virtual machine (VM) until you have "deployed" it. The
            > server knows about URIs to
            > initiate each of the state changes (via a POST), but the
            > representation of the VM lists only the
            > URIs for state transitions that are valid from the current state.
            > This makes it extremely easy
            > for the client to understand that trying to start a VM that hasn't
            > been deployed yet is not legal,
            > because there will be no corresponding URI in the VM representation.
            >
            > * FINE GRAINED EVOLUTION WITHOUT (NECESSARILY) BREAKING OLD CLIENTS.
            > At any given time, the client of any REST API is going to be
            > programmed with *some* assumptions
            > about what the system can do. But, if you document a restriction to
            > "pay attention to only those
            > aspects of the representation that you know about", plus a server
            > side discipline to add things later
            > that don't disrupt previous behavior, you can evolve APIs fairly
            > quickly without breaking all clients,
            > or having to support multiple versions of the API simultaneously on
            > your server. You don't have to
            > wait years for serendipity benefits :-). Especially compared to
            > something like SOAP where the
            > syntax of your representations is versioned (in the WSDL), so you
            > have to mess with the clients
            > on every single change.
            >
            > Having drunk the HATEOAS koolaid now, I would have a really hard time
            > going back :-).
            >
            > Craig McClanahan
            >
            > [1] http://kenai.com/projects/suncloudapis/pages/Home
            >
            > <!-- #ygrp-mkp{ border: 1px solid #d8d8d8; font-family: Arial;
            > margin: 14px 0px; padding: 0px 14px; } #ygrp-mkp hr{ border: 1px
            > solid #d8d8d8; } #ygrp-mkp #hd{ color: #628c2a; font-size: 85%; font-
            > weight: bold; line-height: 122%; margin: 10px 0px; } #ygrp-mkp
            > #ads{ margin-bottom: 10px; } #ygrp-mkp .ad{ padding: 0 0; } #ygrp-
            > mkp .ad a{ color: #0000ff; text-decoration: none; } --> <!-- #ygrp-
            > sponsor #ygrp-lc{ font-family: Arial; } #ygrp-sponsor #ygrp-lc
            > #hd{ margin: 10px 0px; font-weight: bold; font-size: 78%; line-
            > height: 122%; } #ygrp-sponsor #ygrp-lc .ad{ margin-bottom: 10px;
            > padding: 0 0; } --> <!-- #ygrp-mlmsg {font-size:13px; font-family:
            > arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}
            > #ygrp-mlmsg table {font-size:inherit;font:100%;} #ygrp-mlmsg select,
            > input, textarea {font:99% arial,helvetica,clean,sans-serif;} #ygrp-
            > mlmsg pre, code {font:115% monospace;*font-size:100%;} #ygrp-mlmsg *
            > {line-height:1.22em;} #ygrp-text{ font-family: Georgia; } #ygrp-
            > text p{ margin: 0 0 1em 0; } dd.last p a { font-family: Verdana;
            > font-weight: bold; } #ygrp-vitnav{ padding-top: 10px; font-family:
            > Verdana; font-size: 77%; margin: 0; } #ygrp-vitnav a{ padding: 0
            > 1px; } #ygrp-mlmsg #logo{ padding-bottom: 10px; } #ygrp-reco
            > { margin-bottom: 20px; padding: 0px; } #ygrp-reco #reco-head { font-
            > weight: bold; color: #ff7900; } #reco-category{ font-size: 77%; }
            > #reco-desc{ font-size: 77%; } #ygrp-vital a{ text-decoration:
            > none; } #ygrp-vital a:hover{ text-decoration: underline; } #ygrp-
            > sponsor #ov ul{ padding: 0 0 0 8px; margin: 0; } #ygrp-sponsor #ov
            > li{ list-style-type: square; padding: 6px 0; font-size: 77%; } #ygrp-
            > sponsor #ov li a{ text-decoration: none; font-size: 130%; } #ygrp-
            > sponsor #nc{ background-color: #eee; margin-bottom: 20px;
            > padding: 0 8px; } #ygrp-sponsor .ad{ padding: 8px 0; } #ygrp-
            > sponsor .ad #hd1{ font-family: Arial; font-weight: bold; color:
            > #628c2a; font-size: 100%; line-height: 122%; } #ygrp-sponsor .ad
            > a{ text-decoration: none; } #ygrp-sponsor .ad a:hover{ text-
            > decoration: underline; } #ygrp-sponsor .ad p{ margin: 0; } o{font-
            > size: 0; } .MsoNormal{ margin: 0 0 0 0; } #ygrp-text tt{ font-size:
            > 120%; } blockquote{margin: 0 0 0 4px;} .replbq{margin:4} dd.last p
            > span { margin-right: 10px; font-family: Verdana; font-weight:
            > bold; } dd.last p span.yshortcuts { margin-right: 0; } div.photo-
            > title a, div.photo-title a:active, div.photo-title a:hover,
            > div.photo-title a:visited { text-decoration: none; } div.file-title
            > a, div.file-title a:active, div.file-title a:hover, div.file-title
            > a:visited { text-decoration: none; } #ygrp-msg p { clear: both;
            > padding: 15px 0 3px 0; overflow: hidden; } #ygrp-msg p span { color:
            > #1E66AE; font-weight: bold; } div#ygrp-mlmsg #ygrp-msg p a
            > span.yshortcuts { font-family: Verdana; font-size: 10px; font-
            > weight: normal; } #ygrp-msg p a { font-family: Verdana; font-size:
            > 10px; } #ygrp-mlmsg a { color: #1E66AE; } div.attach-table div div a
            > { text-decoration: none; } div.attach-table { width: 400px; } -->
          • Bill Burke
            ... How would you initially define and then evolve your XML schema in such an environment? I know Atom allows arbitrary attributes and elements in its schema
            Message 5 of 27 , Apr 1, 2009
            • 0 Attachment
              Craig McClanahan wrote:
              >
              > * FINE GRAINED EVOLUTION WITHOUT (NECESSARILY) BREAKING OLD CLIENTS.
              > At any given time, the client of any REST API is going to be
              > programmed with *some* assumptions
              > about what the system can do. But, if you document a restriction to
              > "pay attention to only those
              > aspects of the representation that you know about", plus a server
              > side discipline to add things later
              > that don't disrupt previous behavior, you can evolve APIs fairly
              > quickly without breaking all clients,
              > or having to support multiple versions of the API simultaneously on
              > your server. You don't have to
              > wait years for serendipity benefits :-). Especially compared to
              > something like SOAP where the
              > syntax of your representations is versioned (in the WSDL), so you
              > have to mess with the clients
              > on every single change.
              >

              How would you initially define and then evolve your XML schema in such
              an environment? I know Atom allows arbitrary attributes and elements in
              its schema so that it can easily evolve or allow custom data to be
              appended. What about validation though? Too bad XML schema isn't
              polymorphic.

              Another thought I had on HATEOAS was, what about making the links a part
              of your schema? i.e. specifying in your schema the exact relationships
              and types (but not URIs) that will be made available. If you combine
              this with HTTP content negotiation, the client can guarantee a specific
              version of its conversation or business process. It also allows the
              server to tell the client it doesn't support that type of interaction
              anymore.

              BTW, thanks a lot for the explanation. This will help me greatly when
              explaining HATEOAS to colleagues, users, and customers.

              --
              Bill Burke
              JBoss, a division of Red Hat
              http://bill.burkecentral.com
            • wahbedahbe
              ... Actually, I d like to turn this question around. I ve always been confused by what folks who design systems that comply with all of REST except HATEOAS
              Message 6 of 27 , Apr 1, 2009
              • 0 Attachment
                --- In rest-discuss@yahoogroups.com, Solomon Duskis <sduskis@...> wrote:
                > If
                > you're observing all of the REST constraints but HATEOAS, you're may not
                > have a RESTful architecture, but you have something tremendously useful.
                >

                Actually, I'd like to turn this question around.

                I've always been confused by what folks who design systems that comply with all of REST except HATEOAS think they are getting out of it. It makes no sense to me. The only benefit I can think of is that intermediaries have some insight into what is going on. From a practical perspective this means you get caching (yes, theoretically it can be more than caching but most systems stop there). Is that it?

                What do folks think? What are the benefits of a REST - HATEOAS based architecture?
              • Dong Liu
                Good summary. A perspective helped me understand HATEOAS is to think a system as a combination of multiple state machines. These state machines are distributed
                Message 7 of 27 , Apr 1, 2009
                • 0 Attachment
                  Good summary.

                  A perspective helped me understand HATEOAS is to think a system as a
                  combination of multiple state machines. These state machines are
                  distributed and flexible. Hypermedia is the representation of such
                  distributed state machines. Hypermedia makes asynchronous
                  conversations among multiple parties possible and easy.

                  Cheers,

                  Dong

                  On Tue, Mar 31, 2009 at 6:59 PM, Craig McClanahan <craigmcc@...> wrote:
                  > On Tue, Mar 31, 2009 at 5:01 PM, Solomon Duskis <sduskis@...> wrote:
                  >
                  >> [snip]
                  >
                  >> Assuming that the practical barriers of entry are removed, what practical
                  >> benefits will we see?
                  >>
                  >
                  > I know exactly where you are coming from with these questions ... I
                  > felt the same way until recently. I've designed several REST APIs
                  > over the last couple of years, but up until the most recent one, I
                  > designed and documented them in the "typical" way, describing the URI
                  > structure of the application and letting the client figure out what to
                  > send when. My most recent effort is contributing to the design of the
                  > REST architecture for the Sun Cloud API[1] to control virtual
                  > machines and so on. In addition, I'm very focused on writing client
                  > language bindings for this API in multiple languages (Ruby, Python,
                  > Java) ... so I get a first hand feel for programming to this API at a
                  > very low level.
                  >
                  > We started from the presumption that the service would publish only
                  > *one* well-known URI (returning a "cloud" representation containing
                  > representations for, and/or URI links to representations for, all the
                  > cloud resources that are accessible to the calling user). Every other
                  > URI in the entire system (including all those that do state changes)
                  > are discovered by examining these representations. Even in the early
                  > days, I can see some significant, practical, short term benefits we
                  > have gained from taking this approach:
                  >
                  > * REDUCED CLIENT CODING ERRORS. Looking back at all the REST client
                  > side interfaces
                  > that I, or people I work with, have built, about 90% of the bugs
                  > have been in the construction
                  > of the right URIs for the server. Typical mistakes are leaving out
                  > path segments, getting them
                  > in the wrong order, or forgetting to URL encode things. All this
                  > goes away when the server
                  > hands you exactly the right URI to use for every circumstance.
                  >
                  > * REDUCED INVALID STATE TRANSITION CALLS. When the client decides
                  > which URI to call and
                  > when, they run the risk of attempting to request state transitions
                  > that are not valid for the current
                  > state of the server side resource. An example from my problem
                  > domain ... it's not allowed to
                  > "start" a virtual machine (VM) until you have "deployed" it. The
                  > server knows about URIs to
                  > initiate each of the state changes (via a POST), but the
                  > representation of the VM lists only the
                  > URIs for state transitions that are valid from the current state.
                  > This makes it extremely easy
                  > for the client to understand that trying to start a VM that hasn't
                  > been deployed yet is not legal,
                  > because there will be no corresponding URI in the VM representation.
                  >
                  > * FINE GRAINED EVOLUTION WITHOUT (NECESSARILY) BREAKING OLD CLIENTS.
                  > At any given time, the client of any REST API is going to be
                  > programmed with *some* assumptions
                  > about what the system can do. But, if you document a restriction to
                  > "pay attention to only those
                  > aspects of the representation that you know about", plus a server
                  > side discipline to add things later
                  > that don't disrupt previous behavior, you can evolve APIs fairly
                  > quickly without breaking all clients,
                  > or having to support multiple versions of the API simultaneously on
                  > your server. You don't have to
                  > wait years for serendipity benefits :-). Especially compared to
                  > something like SOAP where the
                  > syntax of your representations is versioned (in the WSDL), so you
                  > have to mess with the clients
                  > on every single change.
                  >
                  > Having drunk the HATEOAS koolaid now, I would have a really hard time
                  > going back :-).
                  >
                  > Craig McClanahan
                  >
                  > [1] http://kenai.com/projects/suncloudapis/pages/Home
                  >



                  --
                  http://dongnotes.blogspot.com/
                • Ebenezer Ikonne
                  ... Wouldn t this have to be compared with a totally non-REST solution like SOAP-bad web services? If yes, then quick benefits that come to mind are a (1)a
                  Message 8 of 27 , Apr 1, 2009
                  • 0 Attachment
                    --- In rest-discuss@yahoogroups.com, "wahbedahbe" <andrew.wahbe@...> wrote:
                    >
                    > --- In rest-discuss@yahoogroups.com, Solomon Duskis <sduskis@> wrote:
                    > > If
                    > > you're observing all of the REST constraints but HATEOAS, you're may not
                    > > have a RESTful architecture, but you have something tremendously useful.
                    > >
                    >
                    > Actually, I'd like to turn this question around.
                    >
                    > I've always been confused by what folks who design systems that comply with all of REST except HATEOAS think they are getting out of it. It makes no sense to me. The only benefit I can think of is that intermediaries have some insight into what is going on. From a practical perspective this means you get caching (yes, theoretically it can be more than caching but most systems stop there). Is that it?
                    >
                    > What do folks think? What are the benefits of a REST - HATEOAS based architecture?
                    >

                    Wouldn't this have to be compared with a totally non-REST solution like SOAP-bad web services? If yes, then quick benefits that come to mind are a (1)a much simpler and cleaner api and (2)easier integration.

                    The point (IMO) is that you can't really get the the full benefits of REST-based solution (which implicitly includes HATEOAS) if all the principles/properties are not being followed/used but there are incremental benefits as more and more of the properties are included in the design

                    Eb
                  • Bill Burke
                    ... A message based rather than RPC-based architecture. HTTP content-negotiation. All the HTTP caching semantics that come as a result of constrained
                    Message 9 of 27 , Apr 1, 2009
                    • 0 Attachment
                      wahbedahbe wrote:
                      >
                      > What do folks think? What are the benefits of a REST - HATEOAS based
                      > architecture?

                      A message based rather than RPC-based architecture. HTTP
                      content-negotiation. All the HTTP caching semantics that come as a
                      result of constrained interface. All pretty huge. HATEOAS is only a
                      piece of the pie IMO.


                      --
                      Bill Burke
                      JBoss, a division of Red Hat
                      http://bill.burkecentral.com
                    • Stefan Tilkov
                      I think there are multiple levels of HATEOAS: One is simple linking of information - easy to do, very obvious benefits (of course one could use a different
                      Message 10 of 27 , Apr 1, 2009
                      • 0 Attachment
                        I think there are multiple levels of HATEOAS: One is simple linking of
                        information - easy to do, very obvious benefits (of course one could
                        use a different name for this). The next level is to drive the app
                        state through links, which is quite a bit harder, yet yields more
                        significant benefits.

                        Stefan
                        --
                        Stefan Tilkov, http://www.innoq.com/blog/st/

                        On 01.04.2009, at 17:00, wahbedahbe wrote:

                        > --- In rest-discuss@yahoogroups.com, Solomon Duskis <sduskis@...>
                        > wrote:
                        > > If
                        > > you're observing all of the REST constraints but HATEOAS, you're
                        > may not
                        > > have a RESTful architecture, but you have something tremendously
                        > useful.
                        > >
                        >
                        > Actually, I'd like to turn this question around.
                        >
                        > I've always been confused by what folks who design systems that
                        > comply with all of REST except HATEOAS think they are getting out of
                        > it. It makes no sense to me. The only benefit I can think of is that
                        > intermediaries have some insight into what is going on. From a
                        > practical perspective this means you get caching (yes, theoretically
                        > it can be more than caching but most systems stop there). Is that it?
                        >
                        > What do folks think? What are the benefits of a REST - HATEOAS based
                        > architecture?
                        >
                        >
                        > <!-- #ygrp-mkp{ border: 1px solid #d8d8d8; font-family: Arial;
                        > margin: 14px 0px; padding: 0px 14px; } #ygrp-mkp hr{ border: 1px
                        > solid #d8d8d8; } #ygrp-mkp #hd{ color: #628c2a; font-size: 85%; font-
                        > weight: bold; line-height: 122%; margin: 10px 0px; } #ygrp-mkp
                        > #ads{ margin-bottom: 10px; } #ygrp-mkp .ad{ padding: 0 0; } #ygrp-
                        > mkp .ad a{ color: #0000ff; text-decoration: none; } --> <!-- #ygrp-
                        > sponsor #ygrp-lc{ font-family: Arial; } #ygrp-sponsor #ygrp-lc
                        > #hd{ margin: 10px 0px; font-weight: bold; font-size: 78%; line-
                        > height: 122%; } #ygrp-sponsor #ygrp-lc .ad{ margin-bottom: 10px;
                        > padding: 0 0; } --> <!-- #ygrp-mlmsg {font-size:13px; font-family:
                        > arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}
                        > #ygrp-mlmsg table {font-size:inherit;font:100%;} #ygrp-mlmsg select,
                        > input, textarea {font:99% arial,helvetica,clean,sans-serif;} #ygrp-
                        > mlmsg pre, code {font:115% monospace;*font-size:100%;} #ygrp-mlmsg *
                        > {line-height:1.22em;} #ygrp-text{ font-family: Georgia; } #ygrp-
                        > text p{ margin: 0 0 1em 0; } dd.last p a { font-family: Verdana;
                        > font-weight: bold; } #ygrp-vitnav{ padding-top: 10px; font-family:
                        > Verdana; font-size: 77%; margin: 0; } #ygrp-vitnav a{ padding: 0
                        > 1px; } #ygrp-mlmsg #logo{ padding-bottom: 10px; } #ygrp-reco
                        > { margin-bottom: 20px; padding: 0px; } #ygrp-reco #reco-head { font-
                        > weight: bold; color: #ff7900; } #reco-category{ font-size: 77%; }
                        > #reco-desc{ font-size: 77%; } #ygrp-vital a{ text-decoration:
                        > none; } #ygrp-vital a:hover{ text-decoration: underline; } #ygrp-
                        > sponsor #ov ul{ padding: 0 0 0 8px; margin: 0; } #ygrp-sponsor #ov
                        > li{ list-style-type: square; padding: 6px 0; font-size: 77%; } #ygrp-
                        > sponsor #ov li a{ text-decoration: none; font-size: 130%; } #ygrp-
                        > sponsor #nc{ background-color: #eee; margin-bottom: 20px;
                        > padding: 0 8px; } #ygrp-sponsor .ad{ padding: 8px 0; } #ygrp-
                        > sponsor .ad #hd1{ font-family: Arial; font-weight: bold; color:
                        > #628c2a; font-size: 100%; line-height: 122%; } #ygrp-sponsor .ad
                        > a{ text-decoration: none; } #ygrp-sponsor .ad a:hover{ text-
                        > decoration: underline; } #ygrp-sponsor .ad p{ margin: 0; } o{font-
                        > size: 0; } .MsoNormal{ margin: 0 0 0 0; } #ygrp-text tt{ font-size:
                        > 120%; } blockquote{margin: 0 0 0 4px;} .replbq{margin:4} dd.last p
                        > span { margin-right: 10px; font-family: Verdana; font-weight:
                        > bold; } dd.last p span.yshortcuts { margin-right: 0; } div.photo-
                        > title a, div.photo-title a:active, div.photo-title a:hover,
                        > div.photo-title a:visited { text-decoration: none; } div.file-title
                        > a, div.file-title a:active, div.file-title a:hover, div.file-title
                        > a:visited { text-decoration: none; } #ygrp-msg p { clear: both;
                        > padding: 15px 0 3px 0; overflow: hidden; } #ygrp-msg p span { color:
                        > #1E66AE; font-weight: bold; } div#ygrp-mlmsg #ygrp-msg p a
                        > span.yshortcuts { font-family: Verdana; font-size: 10px; font-
                        > weight: normal; } #ygrp-msg p a { font-family: Verdana; font-size:
                        > 10px; } #ygrp-mlmsg a { color: #1E66AE; } div.attach-table div div a
                        > { text-decoration: none; } div.attach-table { width: 400px; } -->
                      • Craig McClanahan
                        ... Good idea ... should have done that last night: http://blogs.sun.com/craigmcc/entry/why_hateoas Craig
                        Message 11 of 27 , Apr 1, 2009
                        • 0 Attachment
                          On Wed, Apr 1, 2009 at 2:11 AM, <amsmota@...> wrote:
                          > Excellent explanation, you should publish that somewhere for easy reference.
                          > I think this will give me the final argument to convince my boss to give me
                          > the extra-time i need to fully implement hateoas in our infrastructure...

                          Good idea ... should have done that last night:

                          http://blogs.sun.com/craigmcc/entry/why_hateoas

                          Craig
                        • Craig McClanahan
                          ... The snarky answer would be what schema? we don t need no stinkin schema :-). If you are using XML message formats, though, schemas are pretty useful
                          Message 12 of 27 , Apr 1, 2009
                          • 0 Attachment
                            On Wed, Apr 1, 2009 at 6:40 AM, Bill Burke <bburke@...> wrote:
                            > Craig McClanahan wrote:
                            >>
                            >> * FINE GRAINED EVOLUTION WITHOUT (NECESSARILY) BREAKING OLD CLIENTS.
                            >> At any given time, the client of any REST API is going to be
                            >> programmed with *some* assumptions
                            >> about what the system can do. But, if you document a restriction to
                            >> "pay attention to only those
                            >> aspects of the representation that you know about", plus a server
                            >> side discipline to add things later
                            >> that don't disrupt previous behavior, you can evolve APIs fairly
                            >> quickly without breaking all clients,
                            >> or having to support multiple versions of the API simultaneously on
                            >> your server. You don't have to
                            >> wait years for serendipity benefits :-). Especially compared to
                            >> something like SOAP where the
                            >> syntax of your representations is versioned (in the WSDL), so you
                            >> have to mess with the clients
                            >> on every single change.
                            >>
                            >
                            > How would you initially define and then evolve your XML schema in such an
                            > environment?  I know Atom allows arbitrary attributes and elements in its
                            > schema so that it can easily evolve or allow custom data to be appended.
                            >  What about validation though?  Too bad XML schema isn't polymorphic.

                            The snarky answer would be "what schema? we don't need no stinkin' schema" :-).

                            If you are using XML message formats, though, schemas are pretty
                            useful ... not just for validation, but also for code generation of
                            client and server side stubs (such as with Java's JAXB). The
                            situation I would focus on is a client that is programmed to handle
                            version "M" of the schema, and you want to update it for version "N".
                            If you can limit yourself to the following changes:

                            * Any new elements must be optional (minOccurs="0")

                            * No existing required elements can be modified to be optional

                            * Server side processing accepts this representation and takes the
                            missing optional element
                            from an old client (who obviously won't be sending it) to have the
                            same semantic meaning
                            as "assume a default value".

                            If you can do this, and if you're willing to *not* embed a version
                            number in your schema identifier (which is probably too radical for
                            many people -- hence your quite accurate complaints about
                            polymorphism), you can cover a pretty surprising percentage of the
                            typical evolution scenarios that I have seen.

                            On the other hand, there are going to be some kinds of changes where
                            this doesn't work. But embedding links in the HATEOAS manner can
                            still help you. If the server knows what version the client is
                            programmed for (in the Sun Cloud API, we allow but do not require the
                            client ot specify this in an HTTP header), it can send back different
                            URIs (to representations based on different versions of the schema).
                            The server has to be willing to support both, but you can deal with
                            that on the server end in a bunch of different ways (server pool "A"
                            supports version "M" and server pool "B" serves version "N", or write
                            server code that understands both formats, or ...) without the client
                            having to worry about changing their URI generation logic to match the
                            (often changed) rules for version "N".

                            >
                            > Another thought I had on HATEOAS was, what about making the links a part of
                            > your schema?  i.e. specifying in your schema the exact relationships and
                            > types (but not URIs) that will be made available.  If you combine this with
                            > HTTP content negotiation, the client can guarantee a specific version of its
                            > conversation or business process.  It also allows the server to tell the
                            > client it doesn't support that type of interaction anymore.

                            Atom goes towards this direction with the <link> element (which I
                            would evaluate as a candidate representation of relationships any time
                            I was looking at an XML representation, simply because it is pretty
                            familiar to people), where you can optionally specify things like the
                            media type of the response you can expect. But doesn't the OPTIONS
                            command tell you what verbs a particular URI supports?

                            Craig


                            >
                            > BTW, thanks a lot for the explanation.  This will help me greatly when
                            > explaining HATEOAS to colleagues, users, and customers.
                            >
                            > --
                            > Bill Burke
                            > JBoss, a division of Red Hat
                            > http://bill.burkecentral.com
                            >
                          • Craig McClanahan
                            Snipping and interspersing a few comments: ... In the specification, this is described on the various pages like
                            Message 13 of 27 , Apr 1, 2009
                            • 0 Attachment
                              Snipping and interspersing a few comments:

                              On Wed, Apr 1, 2009 at 2:51 AM, Andrew S. Townley <ast@...> wrote:
                              > This was a great post.  I'm looking at doing something similar for an
                              > application as well, but, having looked at the API for the Sun Cloud, I
                              > was planning on taking it a bit further.
                              >
                              > One thing that I see missing is "full disclosure" of the operations
                              > (verbs) to be used as well as differentiation between actions vs.
                              > information.

                              In the specification, this is described on the various pages like
                              <http://kenai.com/projects/suncloudapis/pages/CloudAPIVMRequests>,
                              which describes the set of operations that a VM representation (or,
                              more properly, a URI included in a VM representation). On the wire,
                              if you use the HTTP OPTIONS command to ask the server what verbs are
                              supported by that URI. For example, the URI you get for the "Attach
                              VM to Public Address or VNet" will tell you that it only supports a
                              POST.

                              What we are not including in the representations, at least right now,
                              is media type related restrictions. Partly, that is because many of
                              the operations are in fact polymorphic (what happens depends on what
                              media type you send in a request), and partly (at least in my view) is
                              that client applications using an API are going to have *some*
                              semantic understanding of what is going on, so they will be "hard
                              coding" in a sense which representations to send already, so they
                              don't necessarily need to be told. And, just knowing the media type
                              still doesn't help you understand which fields have which impacts.
                              This is certainly a design principle around which people will have
                              different opinions, but it's the way we have gone so far.

                              >
                              > Don't get me wrong, I think the API you have is pretty good! :)
                              >
                              > However, the only way that I could think of doing what I'm talking about
                              > was to define some kind of envelope, or at least a series of elements
                              > that were influenced by or imported directly the XHTML forms (and/or
                              > possibly XForms) elements to identify what actions were possible for a
                              > given resource.  That way, you'd have the full HATEOAS in the message
                              > and the clients wouldn't have to know anything except how to interpret
                              > the markup.  I guess I should also say that I'm looking at XML
                              > representations here rather than JSON.

                              XML versus JSON shouldn't really matter all that much. Indeed, I've
                              seen lots of APIs that support both syntaxes (especially easy to do in
                              Java if you're using JAX-RS, but not that difficult in other
                              environments).
                              >
                              > I was planning on posting some thoughts on this anyway, but the timing
                              > of this post was too good to pass up.
                              >
                              > What I was thinking was something like:
                              >
                              > <ActionEnvelope>
                              >  <Header>
                              >  <ActionList>
                              >   <Action id="action1" href="uri" method="POST">Human readable description of the action here</Action>
                              >   <Action id="delete" href="uri" method="DELETE">Delete this resource</Action>
                              >   ...
                              >  </ActionList>
                              >  </Header>
                              >  <Body>
                              >  <!-- any content can go here, and client processing will be based on
                              > either the elements or the namespace URI(s) used in the root child
                              > element -->
                              >  </Body>
                              > </ActionEnvelope>
                              >
                              > Now, before everyone gets all fussy and says it's too much like SOAP, it
                              > truly isn't.  The only thing in common is that it uses an envelope.

                              A couple of thoughts and questions:

                              * Why call out DELETE as a separate action? I'd tend to accept a DELETE
                              back to the URI that got me this representation in the first place if I wanted
                              to support that semantic.

                              * It seems like you are focusing on an application environment where the
                              client is a browser, and therefore potentially limited to "form
                              like" behaviors.
                              This leads you to a distinction between the "edit" view of a "read" view of
                              a resource. My preference is to assume that the client just wants the data,
                              and is totally in charge of formatting (you can synthesize a <form> or an
                              XForm in javascript), so I shouldn't make model-versus-view distinctions
                              in the respresentations.

                              >
                              > The other thing to note is that the total transitions available to the
                              > client are the sum of any in-lined (like FORM submissions, regular
                              > hyperlink traversal, etc.) and then any of the other, "meta" actions
                              > possible for the system as a whole defined in the envelope's header.
                              >
                              > I went through several iterations of putting them in in the "real"
                              > resource vs. in the header, but this is where I'm thinking at the
                              > moment, because it allows you to easily process the resource for both
                              > human and machine interaction (the action list becomes a menu, for
                              > example, if the ultimate user agent wants (X)HTML -- this can be
                              > accomplished a number of different ways).
                              >
                              > I was wondering if you guys went through this line of thinking with your
                              > API design and discarded it, or if it was deemed either unnecessary or
                              > too complicated.
                              >
                              > Of course, with this approach your automated user agent still needs to
                              > understand the semantics of the action id's, but this would be published
                              > as part of the API specification, separate from the specification for
                              > the underlying content schema(s), and the inputs required would be fully
                              > supplied after making the request defined by the action.
                              >
                              > This isn't terribly efficient, because an editing operation for the
                              > resource might look like:
                              >
                              > Step 1) Get the resource URI
                              >
                              > Step 2) Process the resource XML, recording the actions
                              >
                              > Step 3) If an action with ID "edit" exists in the header, but no form
                              > exists in the body, make request for "edit" resource
                              >
                              > Step 4) Process the resource XML looking for "resource editing" mark-up
                              > (defined by the API spec, probably a normal FORM in the envelope body)
                              >
                              > Step 5) Supply available form values to be changed (also prevents
                              > changing of read-only resource properties)
                              >
                              > Step 6) Submit FORM
                              >
                              > Step 7) Process HTTP server response
                              >
                              > Granted, this certainly not as efficient as:
                              >
                              >  PUT /vms/33333
                              >  Host: example.com
                              >  Authorization: Basic xxxxxxxxxxxxxxxxxxx
                              >  Accept: application/vnd.com.sun.cloud.VM+json
                              >  Content-Length: nnn
                              >  Content-Type: application/vnd.com.sun.cloud.VM+json
                              >  X-Cloud-Client-Specification-Version: 0.1
                              >
                              >  {
                              >   "description" : "This is the new description"
                              >  }
                              >
                              > But how does the user agent know it can do this from the original
                              > resource?

                              Turn that question around. With your approach, how does the client
                              know what values are valid in any of the input fields? Or what is
                              going to happen to the state of the system when you send in a POST or
                              a PUT or a DELETE? My feeling is that the person developing the
                              client application is going to have to understand this kind of
                              semantics anyway, so let's skip the extra round trips, and all the
                              extra server side logic to create "forms" -- even if the client really
                              is an application that doesn't need such a thing.

                              The other thing I'm doing, which is not obvious in the specification,
                              is writing client language bindings for this API (Java, Ruby, Python
                              to start). You don't have to use them, but it will make life simpler
                              for you. In each language, a VM representation is described as a
                              class VM with attributes/properties for all the fields, plus public
                              methods like attach() and detach() that trigger the POSTs to the
                              appropriate URIs, with the appropriately formatted representations. A
                              client application that leverages a binding like this gets a nice O-O
                              view of the world, and all the stuff we RESTafarians love to argue
                              about is hidden inside a black box :-).

                              I'll be talking more about client bindings once we're ready to publish
                              these as concrete examples ... there are some really interesting
                              decisions in how to represent a REST web service programmatically.
                              But I can tell you that the HATEOAS approach has made writing these
                              clients quite a lot easier.

                              >
                              >  HTTP/1.1 200 OK
                              >  Content-Type: application/vnd.com.sun.cloud.VM+json
                              >  Content-Length: nnn
                              >
                              >  {
                              >   "name" : "web01",
                              >   "uri" : "http://example.com/vms/33333"
                              >   "run_status" : "RUNNING",
                              >   "model_status" : "DEPLOYED",
                              >   "description" : "This is the old description"
                              >   ...
                              >   "back_up" : "http://example.com/back-up?vm=33333"
                              >   "attach" : "http://example.com/attach?vm=33333",
                              >   "detach" : "http://example.com/detach-ip?vm=33333",
                              >   ...
                              >  }
                              >
                              > I realize the propsal above isn't perfect either, but it's really still
                              > in the embryonic phases at the moment.  However, I plan on actually
                              > working through much of the detail over the next few months, so any
                              > feedback (good, bad or otherwise) is welcome.
                              >
                              > The Sun Cloud API is one of the more interesting ones that I've seen
                              > recently, and I'm sure there's lots to learn from it.
                              >
                              > Nice work.

                              Thanks. This API is still evolving, by the way, so feel free to
                              provide any direct feedback on the related wiki (free registration
                              required).

                              >
                              > ast

                              Craig


                              > --
                              > Andrew S. Townley <ast@...>
                              > http://atownley.org
                              >
                              >
                            • Bill Burke
                              ... Not talking about verbs, but links/relationships. Define/require your atom links in your schema so that the client is assured that the links will be there
                              Message 14 of 27 , Apr 1, 2009
                              • 0 Attachment
                                Craig McClanahan wrote:
                                >
                                > Atom goes towards this direction with the <link> element (which I
                                > would evaluate as a candidate representation of relationships any time
                                > I was looking at an XML representation, simply because it is pretty
                                > familiar to people), where you can optionally specify things like the
                                > media type of the response you can expect. But doesn't the OPTIONS
                                > command tell you what verbs a particular URI supports?
                                >

                                Not talking about verbs, but links/relationships. Define/require your
                                atom links in your schema so that the client is assured that the links
                                will be there in the document because of validation.



                                --
                                Bill Burke
                                JBoss, a division of Red Hat
                                http://bill.burkecentral.com
                              • Andrew S. Townley
                                Apologies for the delayed reply. Was away from email for a bit. ... That s cool. However, that s not exactly what I meant by verbs in the above. To me,
                                Message 15 of 27 , Apr 4, 2009
                                • 0 Attachment
                                  Apologies for the delayed reply. Was away from email for a bit.

                                  On Wed, 2009-04-01 at 11:12 -0700, Craig McClanahan wrote:
                                  > Snipping and interspersing a few comments:
                                  >
                                  > On Wed, Apr 1, 2009 at 2:51 AM, Andrew S. Townley <ast@...> wrote:
                                  > > This was a great post. I'm looking at doing something similar for an
                                  > > application as well, but, having looked at the API for the Sun Cloud, I
                                  > > was planning on taking it a bit further.
                                  > >
                                  > > One thing that I see missing is "full disclosure" of the operations
                                  > > (verbs) to be used as well as differentiation between actions vs.
                                  > > information.
                                  >
                                  > In the specification, this is described on the various pages like
                                  > <http://kenai.com/projects/suncloudapis/pages/CloudAPIVMRequests>,
                                  > which describes the set of operations that a VM representation (or,
                                  > more properly, a URI included in a VM representation). On the wire,
                                  > if you use the HTTP OPTIONS command to ask the server what verbs are
                                  > supported by that URI. For example, the URI you get for the "Attach
                                  > VM to Public Address or VNet" will tell you that it only supports a
                                  > POST.

                                  That's cool. However, that's not exactly what I meant by "verbs" in the
                                  above. To me, what we're talking about with REST systems is that the
                                  representations transferred between the client and the server are
                                  pictures of the *application* state, not of the resource state. This is
                                  my understanding of Roy's thesis.

                                  In the degenerate case, the application in question is an HTTP server,
                                  and what it's doing is really pretty simple and defined solely by the
                                  bounds of GET, POST, PUT, DELETE and friends. What I'm talking about
                                  are more complex hypermedia applications which are built according to
                                  the REST architectural style and just happen to be using HTTP to
                                  transfer these representations between the client and the server(s) in
                                  question that comprise the overall application implementation.

                                  In this case, the representations of the application state need to be
                                  more complicated, because the application is more complicated. Of
                                  course, the difference here between browser+human user agents and
                                  automated agents actually doesn't matter in the abstract. Where it
                                  differs is in the concrete implementations of how those application
                                  states are represented to the user agent.

                                  For a browser+human user agent, you can get by with "simpler" (X)HTML
                                  representations of the hypermedia aspects triggering the various state
                                  transitions as well as potentially a few less complicated resource types
                                  like PDFs, images, office documents, etc. that may be part of the
                                  overall application interaction scenarios.

                                  However, in the case of the automated user agent, you can't make those
                                  assumptions because the user agent needs to "understand" what each of
                                  the given application state representations from the server "means", so
                                  that it can do the right thing to accomplish its mission.

                                  You only have two options for doing this:

                                  1) Come up with abstraction(s) to describe these application states with
                                  fixed semantics and then express your application's business logic in
                                  terms of these abstractions, or

                                  2) Implement specific assumptions about the application into your user
                                  agent, and implement your business logic based on those assumptions.

                                  I'm not saying that there is a one-size-fits all solution. What I'm
                                  trying to define with what I outlined earlier is a way to allow you to
                                  do #1 as efficiently as possible in the case where you want the same
                                  client business logic to support as many server implementations as
                                  possible. As you say below, all this overhead where you're primarily in
                                  control of both ends is unnecessary complexity in most cases.

                                  > What we are not including in the representations, at least right now,
                                  > is media type related restrictions. Partly, that is because many of
                                  > the operations are in fact polymorphic (what happens depends on what
                                  > media type you send in a request), and partly (at least in my view) is
                                  > that client applications using an API are going to have *some*
                                  > semantic understanding of what is going on, so they will be "hard
                                  > coding" in a sense which representations to send already, so they
                                  > don't necessarily need to be told. And, just knowing the media type
                                  > still doesn't help you understand which fields have which impacts.
                                  > This is certainly a design principle around which people will have
                                  > different opinions, but it's the way we have gone so far.

                                  Fair enough, and as I said above, it may be the right approach for your
                                  particular application. It is much more closely conforming to option #2
                                  above, but as long as you're clear (and your users are clear), then you
                                  can effectively plan for the evolution of the system on both ends.

                                  > >
                                  > > Don't get me wrong, I think the API you have is pretty good! :)
                                  > >
                                  > > However, the only way that I could think of doing what I'm talking about
                                  > > was to define some kind of envelope, or at least a series of elements
                                  > > that were influenced by or imported directly the XHTML forms (and/or
                                  > > possibly XForms) elements to identify what actions were possible for a
                                  > > given resource. That way, you'd have the full HATEOAS in the message
                                  > > and the clients wouldn't have to know anything except how to interpret
                                  > > the markup. I guess I should also say that I'm looking at XML
                                  > > representations here rather than JSON.
                                  >
                                  > XML versus JSON shouldn't really matter all that much. Indeed, I've
                                  > seen lots of APIs that support both syntaxes (especially easy to do in
                                  > Java if you're using JAX-RS, but not that difficult in other
                                  > environments).

                                  I didn't figure it would, but I just wanted to be clear.

                                  > > I was planning on posting some thoughts on this anyway, but the timing
                                  > > of this post was too good to pass up.
                                  > >
                                  > > What I was thinking was something like:
                                  > >
                                  > > <ActionEnvelope>
                                  > > <Header>
                                  > > <ActionList>
                                  > > <Action id="action1" href="uri" method="POST">Human readable description of the action here</Action>
                                  > > <Action id="delete" href="uri" method="DELETE">Delete this resource</Action>
                                  > > ...
                                  > > </ActionList>
                                  > > </Header>
                                  > > <Body>
                                  > > <!-- any content can go here, and client processing will be based on
                                  > > either the elements or the namespace URI(s) used in the root child
                                  > > element -->
                                  > > </Body>
                                  > > </ActionEnvelope>
                                  > >
                                  > > Now, before everyone gets all fussy and says it's too much like SOAP, it
                                  > > truly isn't. The only thing in common is that it uses an envelope.
                                  >
                                  > A couple of thoughts and questions:
                                  >
                                  > * Why call out DELETE as a separate action? I'd tend to accept a DELETE
                                  > back to the URI that got me this representation in the first place if I wanted
                                  > to support that semantic.

                                  Because in the case of scenario #1 above, you're not talking about HTTP
                                  as the application, you're talking about something different. Even if
                                  you leverage the HTTP verbs and map those to your application as closely
                                  as possible, DELETE might not be supported in your particular
                                  environment. You might have to use POST, or you might have to send the
                                  request to an entirely different URI than the one you used to request
                                  the representation.

                                  That's not pure HTTP, but I don't believe that it isn't still pure REST.
                                  I truly don't see a tight coupling between REST and HTTP, even though
                                  using HTTP in practice to deliver REST systems makes a whole lot of
                                  sense.

                                  To one of your other points about minimizing the number of invalid state
                                  transition requests, it also serves to put all of the valid state
                                  transition information explicitly in the hypermedia representation. You
                                  could do an HTTP OPTIONS request on the resource, but that might not
                                  actually tell you what *application* transitions were available in each
                                  case. It certainly SHOULD do it, but there might not be a good mapping
                                  between application state transitions and HTTP verbs. This approach
                                  ensures a clear separation between the two, using the hypermedia
                                  representation.

                                  > * It seems like you are focusing on an application environment where the
                                  > client is a browser, and therefore potentially limited to "form
                                  > like" behaviors.
                                  > This leads you to a distinction between the "edit" view of a "read" view of
                                  > a resource. My preference is to assume that the client just wants the data,
                                  > and is totally in charge of formatting (you can synthesize a <form> or an
                                  > XForm in javascript), so I shouldn't make model-versus-view distinctions
                                  > in the respresentations.

                                  As I hope is clear now, we're talking about following an "equal
                                  opportunity" principle as far as clients are concerned. Based on the
                                  thinking and research I've done to date on REST and hypermedia-based
                                  systems, I think the issues are the same, it's just that the differences
                                  are collapsed due to the human element in browser-based interactions.

                                  This doesn't mean you're limited to using forms, but if it's the right
                                  tool for the job, there's no reason to re-invent the wheel. That's the
                                  other good thing about XML-based hypermedia: it gives you the ability
                                  to selectively layer in the functionality you need.

                                  >From an API perspective, you call out the application state transitions
                                  as part of the specification and how the client/user agent is supposed
                                  to detect and understand the semantics of said transitions. Then, for
                                  each particular state, you describe the format of the hypermedia the
                                  client is likely to receive.

                                  It still has the opportunity to either fully or partially understand
                                  aspects of the hypermedia representations provided, with either graceful
                                  or un-graceful functionality degradation, depending on the complexity of
                                  the user agent and the needs of the application.

                                  Alternatively, you invert the approach and implement common behavior
                                  based on the clients "detecting" the state of the application from the
                                  representation. Instead of knowing ahead of time that you're supposed
                                  to be able to do "create -> view -> edit | delete", it uses the
                                  representation and an understanding of specific semantics associated
                                  with particular action id's, like view, edit, delete, search, etc. and
                                  its "understanding" of particular representation content formats
                                  together to allow it to successfully interact with the system given a
                                  number of possible starting application states, based on what the
                                  business logic of the client says it's trying to accomplish. This would
                                  be my real goal, actually.

                                  >From a user agent perspective, I don't want to have to provide a
                                  javascript environment for every user agent. From an application
                                  perspective, I see "view representation" and "edit representation" as
                                  being two separate states, potentially with two different representation
                                  formats and even data. For example, you might show relationships
                                  between resources in a view representation, but if it doesn't make sense
                                  to edit these in an edit representation, you wouldn't include them.
                                  Only the data the given user agent could actually change would be
                                  supplied.

                                  The other reason this is where my thinking is right now is that
                                  browser-based hypermedia interactions are the only ones really proven to
                                  fully implement the REST style to date. Other systems implement aspects
                                  of it, or they follow specific semantic mappings between application
                                  state transitions and HTTP state transitions or verbs, but they don't go
                                  "whole hog".

                                  The semweb folks are trying one approach to specifying this, but I think
                                  it doesn't really need to be that complicated to provide practical
                                  solutions to scenario #1 above without trying to eat the whole "W3C
                                  Semantic Web vision" elephant at once.

                                  HTTP is a means to an end in my view. It isn't (and shouldn't) be the
                                  limiting design constraint for RESTful systems. That's the role HATEOAS
                                  plays, not HTTP.

                                  > >
                                  > > The other thing to note is that the total transitions available to the
                                  > > client are the sum of any in-lined (like FORM submissions, regular
                                  > > hyperlink traversal, etc.) and then any of the other, "meta" actions
                                  > > possible for the system as a whole defined in the envelope's header.
                                  > >
                                  > > I went through several iterations of putting them in in the "real"
                                  > > resource vs. in the header, but this is where I'm thinking at the
                                  > > moment, because it allows you to easily process the resource for both
                                  > > human and machine interaction (the action list becomes a menu, for
                                  > > example, if the ultimate user agent wants (X)HTML -- this can be
                                  > > accomplished a number of different ways).
                                  > >
                                  > > I was wondering if you guys went through this line of thinking with your
                                  > > API design and discarded it, or if it was deemed either unnecessary or
                                  > > too complicated.
                                  > >
                                  > > Of course, with this approach your automated user agent still needs to
                                  > > understand the semantics of the action id's, but this would be published
                                  > > as part of the API specification, separate from the specification for
                                  > > the underlying content schema(s), and the inputs required would be fully
                                  > > supplied after making the request defined by the action.
                                  > >
                                  > > This isn't terribly efficient, because an editing operation for the
                                  > > resource might look like:
                                  > >
                                  > > Step 1) Get the resource URI
                                  > >
                                  > > Step 2) Process the resource XML, recording the actions
                                  > >
                                  > > Step 3) If an action with ID "edit" exists in the header, but no form
                                  > > exists in the body, make request for "edit" resource
                                  > >
                                  > > Step 4) Process the resource XML looking for "resource editing" mark-up
                                  > > (defined by the API spec, probably a normal FORM in the envelope body)
                                  > >
                                  > > Step 5) Supply available form values to be changed (also prevents
                                  > > changing of read-only resource properties)
                                  > >
                                  > > Step 6) Submit FORM
                                  > >
                                  > > Step 7) Process HTTP server response
                                  > >
                                  > > Granted, this certainly not as efficient as:
                                  > >
                                  > > PUT /vms/33333
                                  > > Host: example.com
                                  > > Authorization: Basic xxxxxxxxxxxxxxxxxxx
                                  > > Accept: application/vnd.com.sun.cloud.VM+json
                                  > > Content-Length: nnn
                                  > > Content-Type: application/vnd.com.sun.cloud.VM+json
                                  > > X-Cloud-Client-Specification-Version: 0.1
                                  > >
                                  > > {
                                  > > "description" : "This is the new description"
                                  > > }
                                  > >
                                  > > But how does the user agent know it can do this from the original
                                  > > resource?
                                  >
                                  > Turn that question around. With your approach, how does the client
                                  > know what values are valid in any of the input fields? Or what is
                                  > going to happen to the state of the system when you send in a POST or
                                  > a PUT or a DELETE? My feeling is that the person developing the
                                  > client application is going to have to understand this kind of
                                  > semantics anyway, so let's skip the extra round trips, and all the
                                  > extra server side logic to create "forms" -- even if the client really
                                  > is an application that doesn't need such a thing.

                                  I'm not 100% convinced that the user agent needs to fully understand
                                  what's going to happen to the state of the system for each transition.
                                  All it should need to know is how to use the available state transitions
                                  from this particular state representation to accomplish what it's trying
                                  to do. It is likely only concerned with a subset of the overall
                                  application state and available transitions, again, depending on what
                                  it's trying to do and how complex the system actually is.

                                  Again, I'm not saying that what I'm proposing is a one-size-fits all
                                  solution. However, at this stage, I do believe that the client only
                                  needs to know:

                                  a) the available state transitions (based on what it "sees" in the given
                                  representation of the current application state)

                                  b) what each of those state transitions "mean" (their semantics) in
                                  terms of both generic application behavior (CRUD operations, for
                                  example) as well as application-specific behavior (start/stop servers,
                                  etc.) in the context of the job it's trying to do

                                  c) how to recognize appropriate inputs and data provided by the system
                                  and map those to information it holds locally

                                  b & c are the key aspects here. If your user agent is built to
                                  understand that, in general if it sees an HTML form, then it can assume
                                  that the ID values for each of the input elements corresponds to an
                                  object property of an internal object it maintains corresponding to
                                  either the base URI (minus any query parameters) of the resource being
                                  edited or some other identifier present in the hypermedia, then it can
                                  auto-populate the form fields in much the same way that modern browsers
                                  do.

                                  They are also able to mostly do this successfully simply based on the
                                  information provided by the individual HTML elements without any
                                  knowledge of the particular application state. This "caveman
                                  mentality", e.g. "me see form field id; me have data matching form field
                                  id; me populate field", actually seems to work reasonably well.

                                  If your application is written in such a way that it can leverage this
                                  behavior, then I think you've greatly simplified your individual
                                  application clients' business logic definition. Of course, it means
                                  that you might need a more complex interaction library than just using
                                  HTTP, but I don't really see that an an issue.

                                  I want to get to the point where I have the ability to define "simple"
                                  clients based on an understanding of a small set of semantic actions
                                  that can easily be applied across a number of different systems broadly
                                  performing the same task, but with different implementation specifics.

                                  Why, yes, this is a bit of semweb stuff, but rather than saying "how do
                                  I understand the semantics of every possible application interface and
                                  negotiate a way to interact with it," I'm trying to take the approach of
                                  "let's (try) to define a smaller set of semantics that can be broadly
                                  applied and push the burden of mapping to these back to the application
                                  rather than making the client 'smart enough' to figure it out."

                                  I think there's a sweet spot of application types and interactions where
                                  this would be immensely useful. You can argue that you can already do
                                  this kind of mapping with HTTP apis defined in terms of the HTTP verbs,
                                  and that's true in some cases. However, I don't believe that HTTP was
                                  designed to support this particular scenario. Of course, many people
                                  have proven that it can work, but I think there might be a better way.
                                  Presently, I think that "better way" is based on leveraging hypermedia a
                                  lot more than I see in most RESTful systems for automated interaction.

                                  I also realize that there's a ton of implicit assumptions in this
                                  approach as well, but I am trying to make a concerted effort to keep the
                                  interaction assumptions orthogonal to the application assumptions.

                                  > The other thing I'm doing, which is not obvious in the specification,
                                  > is writing client language bindings for this API (Java, Ruby, Python
                                  > to start). You don't have to use them, but it will make life simpler
                                  > for you. In each language, a VM representation is described as a
                                  > class VM with attributes/properties for all the fields, plus public
                                  > methods like attach() and detach() that trigger the POSTs to the
                                  > appropriate URIs, with the appropriately formatted representations. A
                                  > client application that leverages a binding like this gets a nice O-O
                                  > view of the world, and all the stuff we RESTafarians love to argue
                                  > about is hidden inside a black box :-).
                                  >
                                  > I'll be talking more about client bindings once we're ready to publish
                                  > these as concrete examples ... there are some really interesting
                                  > decisions in how to represent a REST web service programmatically.
                                  > But I can tell you that the HATEOAS approach has made writing these
                                  > clients quite a lot easier.

                                  I'm sure that it has, and I think from a pragmatic perspective, you're
                                  taking the right approach to ensure that you've both provided convenient
                                  interaction mechanisms for existing popular environments and allowed you
                                  (or someone else) to implement new ones as needed since you've an open
                                  'on-the-wire' protocol and data formats that leverage functionality
                                  present in just about every modern language environment (an HTTP client
                                  implementation).


                                  > > I realize the propsal above isn't perfect either, but it's really still
                                  > > in the embryonic phases at the moment. However, I plan on actually
                                  > > working through much of the detail over the next few months, so any
                                  > > feedback (good, bad or otherwise) is welcome.
                                  > >
                                  > > The Sun Cloud API is one of the more interesting ones that I've seen
                                  > > recently, and I'm sure there's lots to learn from it.
                                  > >
                                  > > Nice work.
                                  >
                                  > Thanks. This API is still evolving, by the way, so feel free to
                                  > provide any direct feedback on the related wiki (free registration
                                  > required).

                                  If I have anything specifically related to the API, I will certainly
                                  take this approach.

                                  >
                                  > >
                                  > > ast
                                  >
                                  > Craig
                                  >

                                  ast
                                  --
                                  Andrew S. Townley <ast@...>
                                  http://atownley.org
                                • Bill de hOra
                                  ... To turn this round again - I would not agree that all REST benefits are derived from links in content. ... Each principle and constraint adopted gets you
                                  Message 16 of 27 , Apr 4, 2009
                                  • 0 Attachment
                                    wahbedahbe wrote:

                                    > Actually, I'd like to turn this question around.
                                    >
                                    > I've always been confused by what folks who design systems that comply
                                    > with all of REST except HATEOAS think they are getting out of it. It
                                    > makes no sense to me. The only benefit I can think of is that
                                    > intermediaries have some insight into what is going on. From a practical
                                    > perspective this means you get caching (yes, theoretically it can be
                                    > more than caching but most systems stop there). Is that it?

                                    To turn this round again - I would not agree that all REST benefits are
                                    derived from links in content.


                                    > What do folks think? What are the benefits of a REST - HATEOAS based
                                    > architecture?

                                    Each principle and constraint adopted gets you some benefit, and those
                                    are well documented. So the answer seems to the benefits except those
                                    derived from links in content.
                                    Bill
                                  • Bill Burke
                                    ... Sorry to pick out one tiny piece of your excellent post...But... IMO, there are very very few applications/clients that can approach integration in this
                                    Message 17 of 27 , Apr 6, 2009
                                    • 0 Attachment
                                      Andrew S. Townley wrote:
                                      > Alternatively, you invert the approach and implement common behavior
                                      > based on the clients "detecting" the state of the application from the
                                      > representation.


                                      Sorry to pick out one tiny piece of your excellent post...But...

                                      IMO, there are very very few applications/clients that can approach
                                      integration in this manner. In production systems, things have to be
                                      well planned out and predictable or it will just be a disaster.

                                      Bill

                                      --
                                      Bill Burke
                                      JBoss, a division of Red Hat
                                      http://bill.burkecentral.com
                                    • wahbedahbe
                                      Ok, but I m more wondering about the specific gains folks are seeing in practice in the systems they are building. The reason I m curious is because there are
                                      Message 18 of 27 , Apr 6, 2009
                                      • 0 Attachment
                                        Ok, but I'm more wondering about the specific gains folks are seeing in practice in the systems they are building. The reason I'm curious is because there are a lot of frameworks like Rails which claim "RESTfulness" but seem to just deliver REST - HATEOAS (well at least on the "machine to machine" ActiveResource side of things when I last looked at it). Lots of folks seem to think this is really great and is light years better than RPC but I don't really understand why.

                                        Also, things like the idempotency of PUT and DELETE have never yielded any practical benefits to me (though I get how they can in _theory_) so I'm also really curious to know how people are making practical use of them in the systems they are building.

                                        I have personally seen huge gains with "full" REST in systems I've built -- chiefly in decoupling clients and servers (a lot of the stuff Craig McClanahan brings up in this thread) -- and so I really "get" that. REST - HATEOAS -- not so much.

                                        On another note: I think HATEOAS is much more than "links in content" unless your client is something like a spider. What's your take on the discussion here:
                                        http://www.intertwingly.net/blog/2008/03/23/Connecting

                                        Andrew Wahbe

                                        --- In rest-discuss@yahoogroups.com, Bill de hOra <bill@...> wrote:
                                        >
                                        > wahbedahbe wrote:
                                        >
                                        > > Actually, I'd like to turn this question around.
                                        > >
                                        > > I've always been confused by what folks who design systems that comply
                                        > > with all of REST except HATEOAS think they are getting out of it. It
                                        > > makes no sense to me. The only benefit I can think of is that
                                        > > intermediaries have some insight into what is going on. From a practical
                                        > > perspective this means you get caching (yes, theoretically it can be
                                        > > more than caching but most systems stop there). Is that it?
                                        >
                                        > To turn this round again - I would not agree that all REST benefits are
                                        > derived from links in content.
                                        >
                                        >
                                        > > What do folks think? What are the benefits of a REST - HATEOAS based
                                        > > architecture?
                                        >
                                        > Each principle and constraint adopted gets you some benefit, and those
                                        > are well documented. So the answer seems to the benefits except those
                                        > derived from links in content.
                                        > Bill
                                        >
                                      • Assaf Arkin
                                        ... Let s say you re writing a new database server based on a new theory for massively scaling megadata to the cloud. To get taken seriously you ll need
                                        Message 19 of 27 , Apr 6, 2009
                                        • 0 Attachment
                                          On Mon, Apr 6, 2009 at 8:26 AM, wahbedahbe <andrew.wahbe@...> wrote:
                                          Ok, but I'm more wondering about the specific gains folks are seeing in practice in the systems they are building. The reason I'm curious is because there are a lot of frameworks like Rails which claim "RESTfulness" but seem to just deliver REST - HATEOAS (well at least on the "machine to machine" ActiveResource side of things when I last looked at it). Lots of folks seem to think this is really great and is light years better than RPC but I don't really understand why.

                                          Let's say you're writing a new database server based on a new theory for massively scaling megadata to the cloud. To get taken seriously you'll need connectors for Java, .Net and C, with wrappers for PHP, Ruby and Python. That's a lot of connectivity overhead.

                                          Or you can do CRUD over HTTP. You can just adapt a client library from another database, or use one of the many rapid-client devkits out there. You get the four basic operations, authentication, encryption, load balancing and caching out of the box.

                                          Or think about it a different way. I'm writing a script to add user accounts from CSV file onto remote server, I wrote the back-end so I'm in control of the protocol. I can get something up and running with ActiveResource in a few minutes. It won't have the survivability of HATEOAS, but it only takes a few minutes to build and only takes a few minutes to fix.

                                          If you work with HTTP day in an day out, I can see why it would be significantly better to use HTTP over IIOP or RMI or insert-other-binary-format.

                                          Assaf



                                          Also, things like the idempotency of PUT and DELETE have never yielded any practical benefits to me (though I get how they can in _theory_) so I'm also really curious to know how people are making practical use of them in the systems they are building.

                                          I have personally seen huge gains with "full" REST in systems I've built -- chiefly in decoupling clients and servers (a lot of the stuff Craig McClanahan brings up in this thread) -- and so I really "get" that. REST - HATEOAS -- not so much.

                                          On another note: I think HATEOAS is much more than "links in content" unless your client is something like a spider. What's your take on the discussion here:
                                          http://www.intertwingly.net/blog/2008/03/23/Connecting

                                          Andrew Wahbe

                                          --- In rest-discuss@yahoogroups.com, Bill de hOra <bill@...> wrote:
                                          >
                                          > wahbedahbe wrote:
                                          >
                                          > > Actually, I'd like to turn this question around.
                                          > >
                                          > > I've always been confused by what folks who design systems that comply
                                          > > with all of REST except HATEOAS think they are getting out of it. It
                                          > > makes no sense to me. The only benefit I can think of is that
                                          > > intermediaries have some insight into what is going on. From a practical
                                          > > perspective this means you get caching (yes, theoretically it can be
                                          > > more than caching but most systems stop there). Is that it?
                                          >
                                          > To turn this round again - I would not agree that all REST benefits are
                                          > derived from links in content.
                                          >
                                          >
                                          > > What do folks think? What are the benefits of a REST - HATEOAS based
                                          > > architecture?
                                          >
                                          > Each principle and constraint adopted gets you some benefit, and those
                                          > are well documented. So the answer seems to the benefits except those
                                          > derived from links in content.
                                          > Bill
                                          >




                                          ------------------------------------

                                          Yahoo! Groups Links

                                          <*> To visit your group on the web, go to:
                                             http://groups.yahoo.com/group/rest-discuss/

                                          <*> Your email settings:
                                             Individual Email | Traditional

                                          <*> To change settings online go to:
                                             http://groups.yahoo.com/group/rest-discuss/join
                                             (Yahoo! ID required)

                                          <*> To change settings via email:
                                             mailto:rest-discuss-digest@yahoogroups.com
                                             mailto:rest-discuss-fullfeatured@yahoogroups.com

                                          <*> To unsubscribe from this group, send an email to:
                                             rest-discuss-unsubscribe@yahoogroups.com

                                          <*> Your use of Yahoo! Groups is subject to:
                                             http://docs.yahoo.com/info/terms/


                                        • Bill de hOra
                                          ... So for me, some partical things come to mind. - the methods give you high level support for potential operations/scaling pain. Just knowing a system could
                                          Message 20 of 27 , Apr 6, 2009
                                          • 0 Attachment
                                            wahbedahbe wrote:
                                            >
                                            >
                                            > Ok, but I'm more wondering about the specific gains folks are seeing in
                                            > practice in the systems they are building. The reason I'm curious is
                                            > because there are a lot of frameworks like Rails which claim
                                            > "RESTfulness" but seem to just deliver REST - HATEOAS (well at least on
                                            > the "machine to machine" ActiveResource side of things when I last
                                            > looked at it). Lots of folks seem to think this is really great and is
                                            > light years better than RPC but I don't really understand why.
                                            >
                                            > Also, things like the idempotency of PUT and DELETE have never yielded
                                            > any practical benefits to me (though I get how they can in _theory_) so
                                            > I'm also really curious to know how people are making practical use of
                                            > them in the systems they are building.
                                            >
                                            > I have personally seen huge gains with "full" REST in systems I've built
                                            > -- chiefly in decoupling clients and servers (a lot of the stuff Craig
                                            > McClanahan brings up in this thread) -- and so I really "get" that. REST
                                            > - HATEOAS -- not so much.

                                            So for me, some partical things come to mind.

                                            - the methods give you high level support for potential
                                            operations/scaling pain. Just knowing a system could internally be
                                            partitioned at the http level into HEAD/OPTIONS/GET and PUT/POST/DELETE
                                            makes me sleep better at night. Much easier to do it at the load
                                            balancers than in application code imvho.

                                            - PUT and DELETE are useful to have as I don't have to disambiguate
                                            POST. I believe that when smart developers are encouraged to use the
                                            full method set from the get go, they will naturally use POST well and
                                            for dealing with the inevitable corner cases (also forms posting tends
                                            to get used well, which is a big thing for me). So I think having a
                                            method complement helps you fall into the pit of success.

                                            - URL construction (or the lack of). I was reviewing an API today and
                                            realized it could be geolocated by allowing a server to supply URLs to
                                            different domains/administrations. If the clients were putting the URLs
                                            together, that would not work. It also means basic stuff like media
                                            serving/cdns will work when you need them to.

                                            - Well known formats. Or at least well specified ones. You get so much
                                            futureproofing against versioning by making the media type explicit. I'm
                                            not a huge conneg fan (think it doesn't get used well), but the Accept
                                            header is a huge win if you're building something that has to evolve and
                                            support already deployed clients for years to come.

                                            - Caching, but this is well known.

                                            - Organisation of application v resource state. Giving non-domain codey
                                            type things URLs is big win. Jim Webber does a good job here explaining
                                            the practical benefits:
                                            http://www.infoq.com/articles/webber-rest-workflow. I don't know whether
                                            you can express the full BPM/BPEL/piCalculus thing via REST's notions of
                                            state, but I do suspect in many cases you don't need that level of
                                            expressive power.


                                            Ultimately what I get via REST is the notion of applying constraints to
                                            obtain systemic properties. The REST community have done a good job
                                            articulating what happens when you add and remove constraints. It's
                                            objective architectural/systems analysis, not the flimflam I see coming
                                            from EAI/SOA which tend to describe /desirable outcomes/ and not /how to
                                            obtain them/. You don't have to like REST as a style (I personally don't
                                            have much time for the current hype), but you can at least analyse the
                                            design.


                                            > On another note: I think HATEOAS is much more than "links in content"
                                            > unless your client is something like a spider.

                                            Granted, but 'lick' is a better acronym (links in content are king) than
                                            'hateoas' ;)


                                            > What's your take on the
                                            > discussion here:
                                            > http://www.intertwingly.net/blog/2008/03/23/Connecting
                                            > <http://www.intertwingly.net/blog/2008/03/23/Connecting>

                                            I sympathise with Sam's view on things, but still find "connectedness" a
                                            bit abstract. So I distill it even further by asking/cajoling people to
                                            put links in content, to increase the likelihood that a format will be
                                            useful across as many clients as possible.

                                            Bill
                                          • Bill Burke
                                            ... Just curious. Why not a big conneg fan? Is it that you prefer existing, well defined formats? To me, conneg seems to be one of the most powerful
                                            Message 21 of 27 , Apr 7, 2009
                                            • 0 Attachment
                                              Bill de hOra wrote:
                                              > - Well known formats. Or at least well specified ones. You get so much
                                              > futureproofing against versioning by making the media type explicit. I'm
                                              > not a huge conneg fan (think it doesn't get used well), but the Accept
                                              > header is a huge win if you're building something that has to evolve and
                                              > support already deployed clients for years to come.
                                              >

                                              Just curious. Why not a big conneg fan? Is it that you prefer
                                              existing, well defined formats? To me, conneg seems to be one of the
                                              most powerful features of HTTP. Since REST pushes complexity into the
                                              data format, conneg seems uber critical.

                                              --
                                              Bill Burke
                                              JBoss, a division of Red Hat
                                              http://bill.burkecentral.com
                                            • Andrew S. Townley
                                              ... I certainly agree with you that there are very, very few apps that *do* approach integration in this manner, but I don t agree that you can t have apps
                                              Message 22 of 27 , Apr 8, 2009
                                              • 0 Attachment
                                                On Mon, 2009-04-06 at 10:25 -0400, Bill Burke wrote:
                                                >
                                                > Andrew S. Townley wrote:
                                                > > Alternatively, you invert the approach and implement common behavior
                                                > > based on the clients "detecting" the state of the application from the
                                                > > representation.
                                                >
                                                >
                                                > Sorry to pick out one tiny piece of your excellent post...But...
                                                >
                                                > IMO, there are very very few applications/clients that can approach
                                                > integration in this manner. In production systems, things have to be
                                                > well planned out and predictable or it will just be a disaster.

                                                I certainly agree with you that there are very, very few apps that *do*
                                                approach integration in this manner, but I don't agree that you can't
                                                have apps that *can* approach integration in this manner, even in highly
                                                structured, regulated and mission-critical deployments.

                                                You bring up a great point: "if things aren't well planned out and
                                                predictable...things will be a disaster." However, if you stop and
                                                think about it, do you know why this is true?

                                                I've been doing both large & small system integration for over 10 years,
                                                and I've both lived through the reality you described, and also been
                                                trying to find ways to make systems less brittle and more resilient to
                                                change because there's two core axioms of large systems development:

                                                1) Things are going to change between when you start the system and when
                                                you get it "finished", if ever....

                                                2) The system is likely to live far longer than you expect it to

                                                If your integration is based on lots of out-of-band shared knowledge
                                                about the system state transitions, you do need a lot of formal planning
                                                and predictability in the way they work, because you code the endpoints
                                                based on those assumptions. It's really a self-fulfilling prophecy,
                                                actually.

                                                However, if you take the approach that you need to identify and expect a
                                                particular number of states and transitions, each of which are specified
                                                well rather than working from an API reference manual and system user
                                                guide (or functional specification), then you can potentially have more
                                                scalable, flexible and long-lived systems. You can also end up with a
                                                big mess if you don't manage it properly...

                                                I'm not saying that you still won't have to go through a similar amount
                                                of organizational management, politics and pain to arrive at these
                                                "interface" definitions any less than you will for a more traditional
                                                integration approach, but it's the difference in perspective (and
                                                outputs) that matter.

                                                Again, I'm not saying that this approach makes sense for every system on
                                                the planet, but I think it's critical to start thinking differently
                                                about the way we design, implement and extend the large-scale, cross
                                                organisational (and multi-national, in some cases) systems used by every
                                                one of us as businesses and individuals (directly or indirectly) each
                                                day.

                                                Another key point to remember: I'm not talking about altering the
                                                mission profile of the particular application or system, I'm simply
                                                focused on taking a (perhaps radically) different approach to how those
                                                systems interact to deliver the system's mission profile and the
                                                corresponding long-term business objectives of those who built and
                                                operate it.

                                                Cheers,

                                                ast
                                                --
                                                Andrew S. Townley <ast@...>
                                                http://atownley.org
                                              • Bill Burke
                                                ... Its true because stable systems are well tested. You can t test variability. ... FYI, I wasn t bashing HATEOAS. I think it is extremely useful to have
                                                Message 23 of 27 , Apr 8, 2009
                                                • 0 Attachment
                                                  Andrew S. Townley wrote:
                                                  > On Mon, 2009-04-06 at 10:25 -0400, Bill Burke wrote:
                                                  >> Andrew S. Townley wrote:
                                                  >>> Alternatively, you invert the approach and implement common behavior
                                                  >>> based on the clients "detecting" the state of the application from the
                                                  >>> representation.
                                                  >>
                                                  >> Sorry to pick out one tiny piece of your excellent post...But...
                                                  >>
                                                  >> IMO, there are very very few applications/clients that can approach
                                                  >> integration in this manner. In production systems, things have to be
                                                  >> well planned out and predictable or it will just be a disaster.
                                                  >
                                                  > I certainly agree with you that there are very, very few apps that *do*
                                                  > approach integration in this manner, but I don't agree that you can't
                                                  > have apps that *can* approach integration in this manner, even in highly
                                                  > structured, regulated and mission-critical deployments.
                                                  >
                                                  > You bring up a great point: "if things aren't well planned out and
                                                  > predictable...things will be a disaster." However, if you stop and
                                                  > think about it, do you know why this is true?
                                                  >

                                                  Its true because stable systems are well tested. You can't test
                                                  variability.

                                                  > I've been doing both large & small system integration for over 10 years,
                                                  > and I've both lived through the reality you described, and also been
                                                  > trying to find ways to make systems less brittle and more resilient to
                                                  > change because there's two core axioms of large systems development:
                                                  >
                                                  > 1) Things are going to change between when you start the system and when
                                                  > you get it "finished", if ever....
                                                  >
                                                  > 2) The system is likely to live far longer than you expect it to
                                                  >
                                                  > If your integration is based on lots of out-of-band shared knowledge
                                                  > about the system state transitions, you do need a lot of formal planning
                                                  > and predictability in the way they work, because you code the endpoints
                                                  > based on those assumptions. It's really a self-fulfilling prophecy,
                                                  > actually.
                                                  >
                                                  > However, if you take the approach that you need to identify and expect a
                                                  > particular number of states and transitions, each of which are specified
                                                  > well rather than working from an API reference manual and system user
                                                  > guide (or functional specification), then you can potentially have more
                                                  > scalable, flexible and long-lived systems. You can also end up with a
                                                  > big mess if you don't manage it properly...
                                                  >

                                                  FYI, I wasn't bashing HATEOAS. I think it is extremely useful to have
                                                  relationship links embedded in your messages and to traverse these
                                                  links. I just don't think its realistic to think that a client is going
                                                  to be able to make state transition decisions dynamically based on
                                                  looking at a self-describing message. Machines aren't humans.


                                                  --
                                                  Bill Burke
                                                  JBoss, a division of Red Hat
                                                  http://bill.burkecentral.com
                                                Your message has been successfully submitted and would be delivered to recipients shortly.