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

URI design, part 2

Expand Messages
  • Max Toro
    Thanks for your answers, it s pretty much what I had in mind. I want to discuss a second example: a) POST /orders/1/cancel vs. b) PATCH /orders/1 canceled=true
    Message 1 of 28 , Nov 30, 2012
    • 0 Attachment
      Thanks for your answers, it's pretty much what I had in mind.

      I want to discuss a second example:

      a)
      POST /orders/1/cancel

      vs.

      b)
      PATCH /orders/1

      canceled=true


      Does REST say anything in favor or against these two designs?

      Personally, I would never do 'b' because it's simply hard to implement
      with the tools I use. Also, isn't it a case of tunneling? 'Cancel' is
      an action that does more than simply update a resource.

      --
      Max Toro
    • Ian Joyce
      REST says nothing in favor or against either of those two designs
      Message 2 of 28 , Nov 30, 2012
      • 0 Attachment
         REST says nothing in favor or against either of those two designs

        On Fri, Nov 30, 2012 at 7:15 AM, Max Toro <maxtoroq@...> wrote:
        REST say anything in favor or against these two designs

      • Nicholas Shanks
        ... REST says Do b , never a . Sorry! The simple rule is URIs are for nouns, HTTP methods are for verbs. You could get away with this though: POST
        Message 3 of 28 , Nov 30, 2012
        • 0 Attachment
          On 30 Nov 2012, at 13:15, Max Toro wrote:

          > Thanks for your answers, it's pretty much what I had in mind.
          >
          > I want to discuss a second example:
          >
          > a)
          > POST /orders/1/cancel
          >
          > vs.
          >
          > b)
          > PATCH /orders/1
          >
          > canceled=true
          >
          >
          > Does REST say anything in favor or against these two designs?

          REST says "Do 'b', never 'a'." Sorry!
          The simple rule is URIs are for nouns, HTTP methods are for verbs.

          You could get away with this though:

          POST /orders/1
          cancelled=true

          Originally, POST was intended to mean "post a reply" the same as it's NNTP namesake/predecessor. Now, though, the authors of HTTP concede that it's modern meaning is "Hey, server, use these data (request body) to perform some action to this resource (uri)"

          As such, by POSTing to /orders/1 you are at least getting the resource part of the API right, even if you are lacking the semantics of a PATCH request.

          > Personally, I would never do 'b' because it's simply hard to implement
          > with the tools I use. Also, isn't it a case of tunneling? 'Cancel' is
          > an action that does more than simply update a resource.


          I wouldn't call it tunnelling, tunnelling would be something like:

          POST /orders/1

          _method_override="DELETE" // could also be custom HTTP header

          If the "cancel" action is just updating a resource state, rather then, say, DELETEing the resource, then you could even do something like:

          PUT /orders/1/cancelled
          true

          (again, use POST if you can't PUT)

          and correspondingly:

          GET /orders/1/cancelled

          => "true"

          GET /orders/2/cancelled

          => "false"

          (or 1/0, yes/no, … however you wish to represent it)


          For reference, stackoverflow.com is a good place to go with these sorts of questions. Many have already been asked in various forms, you'll find the answers already provided.

          — Nicholas.
        • Jan Algermissen
          ... Yes, right. If it suits your use cases, consider: DELETE /orders/1 Which might well result in the order being moved to a cancled-orders collection. IOW, it
          Message 4 of 28 , Nov 30, 2012
          • 0 Attachment
            On Nov 30, 2012, at 7:08 PM, Nicholas Shanks <nickshanks@...> wrote:

            > On 30 Nov 2012, at 13:15, Max Toro wrote:
            >
            >> Thanks for your answers, it's pretty much what I had in mind.
            >>
            >> I want to discuss a second example:
            >>
            >> a)
            >> POST /orders/1/cancel
            >>
            >> vs.
            >>
            >> b)
            >> PATCH /orders/1
            >>
            >> canceled=true
            >>
            >>
            >> Does REST say anything in favor or against these two designs?
            >
            > REST says "Do 'b', never 'a'." Sorry!

            Yes, right.

            If it suits your use cases, consider:

            DELETE /orders/1

            Which might well result in the order being moved to a cancled-orders collection. IOW, it need not be erased entirely.

            Jan





            > The simple rule is URIs are for nouns, HTTP methods are for verbs.
            >
            > You could get away with this though:
            >
            > POST /orders/1
            > cancelled=true
            >
            > Originally, POST was intended to mean "post a reply" the same as it's NNTP namesake/predecessor. Now, though, the authors of HTTP concede that it's modern meaning is "Hey, server, use these data (request body) to perform some action to this resource (uri)"
            >
            > As such, by POSTing to /orders/1 you are at least getting the resource part of the API right, even if you are lacking the semantics of a PATCH request.
            >
            >> Personally, I would never do 'b' because it's simply hard to implement
            >> with the tools I use. Also, isn't it a case of tunneling? 'Cancel' is
            >> an action that does more than simply update a resource.
            >
            >
            > I wouldn't call it tunnelling, tunnelling would be something like:
            >
            > POST /orders/1
            >
            > _method_override="DELETE" // could also be custom HTTP header
            >
            > If the "cancel" action is just updating a resource state, rather then, say, DELETEing the resource, then you could even do something like:
            >
            > PUT /orders/1/cancelled
            > true
            >
            > (again, use POST if you can't PUT)
            >
            > and correspondingly:
            >
            > GET /orders/1/cancelled
            >
            > => "true"
            >
            > GET /orders/2/cancelled
            >
            > => "false"
            >
            > (or 1/0, yes/no, … however you wish to represent it)
            >
            >
            > For reference, stackoverflow.com is a good place to go with these sorts of questions. Many have already been asked in various forms, you'll find the answers already provided.
            >
            > — Nicholas.
            >
            >
            > ------------------------------------
            >
            > Yahoo! Groups Links
            >
            >
            >
          • Erik Wilde
            +1 on this, it probably would be a good mapping of domain interactions to HTTP verbs. ... -- erik wilde | mailto:dret@berkeley.edu - tel:+1-510-2061079 |
            Message 5 of 28 , Nov 30, 2012
            • 0 Attachment
              +1 on this, it probably would be a good mapping of domain interactions
              to HTTP verbs.

              On 2012-11-30 10:43 , Jan Algermissen wrote:
              >
              > On Nov 30, 2012, at 7:08 PM, Nicholas Shanks <nickshanks@...> wrote:
              >
              >> On 30 Nov 2012, at 13:15, Max Toro wrote:
              >>
              >>> Thanks for your answers, it's pretty much what I had in mind.
              >>>
              >>> I want to discuss a second example:
              >>>
              >>> a)
              >>> POST /orders/1/cancel
              >>>
              >>> vs.
              >>>
              >>> b)
              >>> PATCH /orders/1
              >>>
              >>> canceled=true
              >>>
              >>>
              >>> Does REST say anything in favor or against these two designs?
              >>
              >> REST says "Do 'b', never 'a'." Sorry!
              >
              > Yes, right.
              >
              > If it suits your use cases, consider:
              >
              > DELETE /orders/1
              >
              > Which might well result in the order being moved to a cancled-orders collection. IOW, it need not be erased entirely.
              >
              > Jan
              >
              >
              >
              >
              >
              >> The simple rule is URIs are for nouns, HTTP methods are for verbs.
              >>
              >> You could get away with this though:
              >>
              >> POST /orders/1
              >> cancelled=true
              >>
              >> Originally, POST was intended to mean "post a reply" the same as it's NNTP namesake/predecessor. Now, though, the authors of HTTP concede that it's modern meaning is "Hey, server, use these data (request body) to perform some action to this resource (uri)"
              >>
              >> As such, by POSTing to /orders/1 you are at least getting the resource part of the API right, even if you are lacking the semantics of a PATCH request.
              >>
              >>> Personally, I would never do 'b' because it's simply hard to implement
              >>> with the tools I use. Also, isn't it a case of tunneling? 'Cancel' is
              >>> an action that does more than simply update a resource.
              >>
              >>
              >> I wouldn't call it tunnelling, tunnelling would be something like:
              >>
              >> POST /orders/1
              >>
              >> _method_override="DELETE" // could also be custom HTTP header
              >>
              >> If the "cancel" action is just updating a resource state, rather then, say, DELETEing the resource, then you could even do something like:
              >>
              >> PUT /orders/1/cancelled
              >> true
              >>
              >> (again, use POST if you can't PUT)
              >>
              >> and correspondingly:
              >>
              >> GET /orders/1/cancelled
              >>
              >> => "true"
              >>
              >> GET /orders/2/cancelled
              >>
              >> => "false"
              >>
              >> (or 1/0, yes/no, … however you wish to represent it)
              >>
              >>
              >> For reference, stackoverflow.com is a good place to go with these sorts of questions. Many have already been asked in various forms, you'll find the answers already provided.
              >>
              >> — Nicholas.
              >>
              >>
              >> ------------------------------------
              >>
              >> Yahoo! Groups Links
              >>
              >>
              >>
              >
              >
              >
              > ------------------------------------
              >
              > Yahoo! Groups Links
              >
              >
              >

              --
              erik wilde | mailto:dret@... - tel:+1-510-2061079 |
              | UC Berkeley - School of Information (ISchool) |
              | http://dret.net/netdret http://twitter.com/dret |
            • Eric J. Bowman
              +1 to the other answers you ve gotten. Except... REST is about optimizing the hell out of GET. The hypertext containing the PUT control is one place to GET
              Message 6 of 28 , Nov 30, 2012
              • 0 Attachment
                +1 to the other answers you've gotten. Except...

                REST is about optimizing the hell out of GET. The hypertext containing
                the PUT control is one place to GET the order status. But, why cache-
                expire the entire record when only one string is changed, multiple times
                after the order is placed and becomes static? A RESTful order-status
                API should separate the dynamic aspects of order processing from the
                static, as sub-resources, and manipulate *those* to alter a dynamic
                representation of the static order. This becomes especially efficient
                when, say, a CC is rejected and the customer needs to enter another one.

                Consider PUT /orders/1/status with strings like placed, processing,
                pending, and the tracking # from the shipper -- I'd even consider
                application/xml and application/json acceptable media types for a
                snippet like this, of course not for the hypertext control defining the
                PUT. I'd never PUT 'canceled', I'd use DELETE as Jan described, which
                would trigger a reshelving-fee transaction, with /status returning
                reshelving on 200 OK, before /orders/1* return 410 Gone, indicating the
                transaction has been fully reversed including by the inventory system.

                Using code-on-demand to fill in the current status on the PUT control
                exposes a status API which may be utilized many different ways (push,
                poll, etc.), allowing for serendipitous re-use. The downside of being
                an additional round-trip is mitigated by using compression such that the
                /status 200 OK response fits in one IP packet. Note that XForms may be
                used to make this code declarative, avoiding the optional constraint.

                This thread isn't about URI design at all, in fact it's irrelevant to
                this discussion about hypertext-driven application state, as is method
                selection. Also RESTful: /CRMapp?order=1&query=status on GET, and
                /CRMapp?order=1&status=canceled on POST using application/x-www-form-
                urlencoded, if we assume the hypertext constraint is met, which is what
                this thread is really about.

                Then we can discuss the pros and cons of various media types which can
                implement a RESTful status API, regardless of how the shopping cart is
                implemented. If you're working with making a legacy system more
                RESTful over time, you may want HTML 4, JS and POST. If this is
                greenfield, you may consider XForms w/ PUT and DELETE. Or, use HTML 5
                if this is a Web system, not sure where it is regarding PUT/DELETE, but
                it really doesn't matter...

                The key is the architectural consideration of using subresources for
                dynamic elements like order status, allowing the order itself to become
                sticky in the client-side cache, while also allowing manipulation of
                that resource to occur in one-IP-packet round-trips. Optimizing
                PUT/POST/PATCH doesn't amount to much in the grand scheme of things,
                what counts is optimizing GET by making static all those bytes which
                make up the order being processed, and manipulating its subresources.

                The hypertext interface doesn't even have to reflect the strings
                in /status, it could be a graphical progress bar followed by e-mailing
                the tracking number (instead of, or in addition to, displaying it). Or,
                the strings in /status 200 OK could be numerals, whose semantics are
                conveyed by the PUT control or other hypertext conveying order status.

                Always remember REST is an architectural style, not implementation
                guidelines. If you take one thing from it, it should be "optimize GET
                to maximize caching." Then, any implementation mistakes you make are
                correctable down the line, instead of coming here and being told to go
                back to the drawing board -- iow, if you've separated static from
                dynamic as an architectural pattern, then we can make changes to URIs
                and methods based on what media types are most appropriate for your
                application, because that'll be bikeshedding if you get your resources
                right.

                I prefer developing REST systems in XForms, makes it easy to separate
                static from dynamic in declarative code, to get a handle on what your
                resources *are* and how they relate to one another. I call this
                hypertext-constraint-centric development. The result is a hypertext API
                which may then be implemented any way it needs to be, letting the
                implementation requirements dictate the system's ultimate hypertext, URI
                allocation scheme, and media types if (most likely) XForms isn't
                appropriate. I may hate my HTML 4 implementations' URIs and methods,
                but the underlying systems are implicitly RESTful and thus easy to
                upgrade over time, as new hypertext technology emerges and matures.

                -Eric

                On Fri, 30 Nov 2012 10:45:26 -0800
                Erik Wilde <dret@...> wrote:

                > +1 on this, it probably would be a good mapping of domain
                > interactions to HTTP verbs.
                >
                > On 2012-11-30 10:43 , Jan Algermissen wrote:
                > >
                > > On Nov 30, 2012, at 7:08 PM, Nicholas Shanks
                > > <nickshanks@...> wrote:
                > >
                > >> On 30 Nov 2012, at 13:15, Max Toro wrote:
                > >>
                > >>> Thanks for your answers, it's pretty much what I had in mind.
                > >>>
                > >>> I want to discuss a second example:
                > >>>
                > >>> a)
                > >>> POST /orders/1/cancel
                > >>>
                > >>> vs.
                > >>>
                > >>> b)
                > >>> PATCH /orders/1
                > >>>
                > >>> canceled=true
                > >>>
                > >>>
                > >>> Does REST say anything in favor or against these two designs?
                > >>
                > >> REST says "Do 'b', never 'a'." Sorry!
                > >
                > > Yes, right.
                > >
                > > If it suits your use cases, consider:
                > >
                > > DELETE /orders/1
                > >
                > > Which might well result in the order being moved to a
                > > cancled-orders collection. IOW, it need not be erased entirely.
                > >
                > > Jan
                > >
                > >
                > >
                > >
                > >
                > >> The simple rule is URIs are for nouns, HTTP methods are for verbs.
                > >>
                > >> You could get away with this though:
                > >>
                > >> POST /orders/1
                > >> cancelled=true
                > >>
                > >> Originally, POST was intended to mean "post a reply" the same as
                > >> it's NNTP namesake/predecessor. Now, though, the authors of HTTP
                > >> concede that it's modern meaning is "Hey, server, use these data
                > >> (request body) to perform some action to this resource (uri)"
                > >>
                > >> As such, by POSTing to /orders/1 you are at least getting the
                > >> resource part of the API right, even if you are lacking the
                > >> semantics of a PATCH request.
                > >>
                > >>> Personally, I would never do 'b' because it's simply hard to
                > >>> implement with the tools I use. Also, isn't it a case of
                > >>> tunneling? 'Cancel' is an action that does more than simply
                > >>> update a resource.
                > >>
                > >>
                > >> I wouldn't call it tunnelling, tunnelling would be something like:
                > >>
                > >> POST /orders/1
                > >>
                > >> _method_override="DELETE" // could also be custom HTTP header
                > >>
                > >> If the "cancel" action is just updating a resource state, rather
                > >> then, say, DELETEing the resource, then you could even do
                > >> something like:
                > >>
                > >> PUT /orders/1/cancelled
                > >> true
                > >>
                > >> (again, use POST if you can't PUT)
                > >>
                > >> and correspondingly:
                > >>
                > >> GET /orders/1/cancelled
                > >>
                > >> => "true"
                > >>
                > >> GET /orders/2/cancelled
                > >>
                > >> => "false"
                > >>
                > >> (or 1/0, yes/no, … however you wish to represent it)
                > >>
                > >>
                > >> For reference, stackoverflow.com is a good place to go with these
                > >> sorts of questions. Many have already been asked in various forms,
                > >> you'll find the answers already provided.
                > >>
                > >> — Nicholas.
                > >>
                > >>
                > >> ------------------------------------
                > >>
                > >> Yahoo! Groups Links
                > >>
                > >>
                > >>
                > >
                > >
                > >
                > > ------------------------------------
                > >
                > > Yahoo! Groups Links
                > >
                > >
                > >
                >
                > --
                > erik wilde | mailto:dret@... - tel:+1-510-2061079 |
                > | UC Berkeley - School of Information (ISchool) |
                > | http://dret.net/netdret http://twitter.com/dret |
              • Eric J. Bowman
                ... Pretty good answer, except for that... Welcome to rest-discuss! ;-) Here, the archives are full of list regulars being told directly by the likes of Roy
                Message 7 of 28 , Nov 30, 2012
                • 0 Attachment
                  Nicholas Shanks wrote:
                  >
                  > For reference, stackoverflow.com is a good place to go with these
                  > sorts of questions. Many have already been asked in various forms,
                  > you'll find the answers already provided.
                  >

                  Pretty good answer, except for that... Welcome to rest-discuss! ;-)

                  Here, the archives are full of list regulars being told directly by the
                  likes of Roy and Mark dozens of times that we're wrong. Gradually,
                  this group has become _the_ place to get schooled on REST as intended
                  by Fielding. There, I don't see many answers from those who've put
                  their knowledge to the test, here. What I do see are attempts to define
                  REST in terms of implementation rather than style, i.e. Wikipedia REST,
                  not Fielding REST.

                  So pick the place that best suits your needs -- there if you want
                  implementation, here if you want architecture; there is a difference,
                  which comes down to the proportion of answers from those who've been
                  "vetted" by Roy (and Mark, and others) over the years, and understand
                  REST as an architectural style as opposed to implementation guidelines.

                  Just my two cents.

                  -Eric
                • Will Hartung
                  ... Unless your in a mobile environment where latency mutders you and compression is a secondary benefit. ... -- CONFIDENTIALITY NOTICE: The information
                  Message 8 of 28 , Nov 30, 2012
                  • 0 Attachment
                    On Friday, November 30, 2012, Eric J. Bowman wrote:

                    The downside of being
                    an additional round-trip is mitigated by using compression such that the
                    /status 200 OK response fits in one IP packet. 

                    Unless your in a mobile environment where latency mutders you and compression is a secondary benefit.  

                    CONFIDENTIALITY NOTICE: The information contained in this electronic transmission may be confidential. If you are not an intended recipient, be aware that any disclosure, copying, distribution or use of the information contained in this transmission is prohibited and may be unlawful. If you have received this transmission in error, please notify us by email reply and then erase it from your computer system.
                  • Max Toro
                    What I d love to get is an answer like: POST /orders/1/cancel is not REST compliant because chapter x of Fielding s dissertation explicitly or implicitly says
                    Message 9 of 28 , Nov 30, 2012
                    • 0 Attachment
                      What I'd love to get is an answer like: POST /orders/1/cancel is not
                      REST compliant because chapter x of Fielding's dissertation explicitly
                      or implicitly says it's not allowed or it's discouraged. After knowing
                      what is or isn't REST then I'd love to learn more about the pros and
                      cons of different architectural and implementation styles.
                      --
                      Max Toro


                      On Fri, Nov 30, 2012 at 6:12 PM, Eric J. Bowman <eric@...> wrote:
                      > Nicholas Shanks wrote:
                      >>
                      >> For reference, stackoverflow.com is a good place to go with these
                      >> sorts of questions. Many have already been asked in various forms,
                      >> you'll find the answers already provided.
                      >>
                      >
                      > Pretty good answer, except for that... Welcome to rest-discuss! ;-)
                      >
                      > Here, the archives are full of list regulars being told directly by the
                      > likes of Roy and Mark dozens of times that we're wrong. Gradually,
                      > this group has become _the_ place to get schooled on REST as intended
                      > by Fielding. There, I don't see many answers from those who've put
                      > their knowledge to the test, here. What I do see are attempts to define
                      > REST in terms of implementation rather than style, i.e. Wikipedia REST,
                      > not Fielding REST.
                      >
                      > So pick the place that best suits your needs -- there if you want
                      > implementation, here if you want architecture; there is a difference,
                      > which comes down to the proportion of answers from those who've been
                      > "vetted" by Roy (and Mark, and others) over the years, and understand
                      > REST as an architectural style as opposed to implementation guidelines.
                      >
                      > Just my two cents.
                      >
                      > -Eric
                    • Eric J. Bowman
                      ... Right, YMMV with compression, but the main point is that the bulk of the order is static data and therefore may be made highly persistent in the client
                      Message 10 of 28 , Nov 30, 2012
                      • 0 Attachment
                        Will Hartung wrote:
                        >
                        > >
                        > > The downside of being
                        > > an additional round-trip is mitigated by using compression such
                        > > that the /status 200 OK response fits in one IP packet.
                        > >
                        > Unless your in a mobile environment where latency mutders you and
                        > compression is a secondary benefit.
                        >

                        Right, YMMV with compression, but the main point is that the bulk of
                        the order is static data and therefore may be made highly persistent in
                        the client cache (cache-control: private), _that_ is how both round
                        trips and the transfer of a significant amount of bytes may be avoided,
                        even without optionally compressing certain traffic into one IP packet.
                        Architecture vs. implementation. That being said...

                        I don't understand why compression is bad for latency, though. I cache
                        compressed data, and unzip it on the fly, so the expensive zip operation
                        is only done once by the server each time the resource is updated. Which
                        means the only user who experiences zip latency, is the user who updates
                        the resource -- but does another second (if that) get perceived by the
                        user on PUT/POST/PATCH operations, and is there any real benefit to
                        optimizing these operations when GET is only like a billion times more
                        common a request method? I think not.

                        Are mobile clients still so underpowered that their zip/unzip latency
                        exceeds the transfer gains? Especially if we're talking about
                        manipulating resources and updating representations using one single-
                        packet-each-way round trip, double especially if we're talking about
                        users who are, you know, *mobile*. If the client is moving from one
                        access point to another, caching the bulk of the data on the client and
                        using single-packet messaging is guaranteed to avoid the huge latency
                        hit of changing IP address/routing while manipulating a resource, which
                        seems to me like a huge gain in user-perceived performance.

                        -Eric
                      • Eric J. Bowman
                        Technically, of course, I mean high probability of being a single packet when arbitrarily small messages (including headers) have their payload compressed.
                        Message 11 of 28 , Nov 30, 2012
                        • 0 Attachment
                          Technically, of course, I mean "high probability of being a single
                          packet" when arbitrarily small messages (including headers) have their
                          payload compressed. This also depends on protocol -- HTTP 2 will allow
                          larger payloads to be compressed to one packet by slimming down header
                          size compared to HTTP 1.1, for example.

                          -Eric
                        • Eric J. Bowman
                          ... Well, what are you expecting to GET from /cancel, or are you just using that URL to invoke a procedure? If so, then there are a few places Roy s thesis
                          Message 12 of 28 , Nov 30, 2012
                          • 0 Attachment
                            Max Toro wrote:
                            >
                            > What I'd love to get is an answer like: POST /orders/1/cancel is not
                            > REST compliant because chapter x of Fielding's dissertation explicitly
                            > or implicitly says it's not allowed or it's discouraged. After knowing
                            > what is or isn't REST then I'd love to learn more about the pros and
                            > cons of different architectural and implementation styles.
                            >

                            Well, what are you expecting to GET from /cancel, or are you just using
                            that URL to invoke a procedure? If so, then there are a few places Roy's
                            thesis admonishes against it in Chapter 6 -- the rest of REST is about
                            positive, rather than negative, reinforcement of the identification of
                            resources constraint. Suggested reading: 6.5.2; 6.2.1, in particular:
                            "REST [defines] a resource to be the semantics of what the author
                            intends to identify."

                            Not the semantics of a method invocation. What does /cancel identify?
                            Sounds to me like a method of tunneling DELETE through POST which
                            identifies nothing, iow a procedure endpoint, which is characteristic
                            of various styles but not of the REST style. The hypertext constraint
                            only makes sense if your resources make sense, in that their URLs are
                            identifiers rather than endpoints.

                            Roy's thesis really must be considered in its entirety, to understand
                            the uniform interface constraint (of which identification of resources
                            is a sub-constraint). Chapter 1 introduces the notion of applying
                            design-by-constraint to networked software architecture, as inspired
                            by Eames IIRC. "A style is a named set of constraints on architectural
                            elements that induces the set of properties desired of the
                            architecture." (4.3)

                            Chapter 2 defines terminology associated with networked software
                            architecture, which is required for understanding Chapter 3, which lays
                            out a methodology for evaluating various styles and applies this to
                            several examples. Most importantly, Chapter 3 identifies the
                            constraints associated with various styles, and describes the properties
                            they induce in a system (which may or may not be beneficial or
                            detrimental to the system you're designing; remember there is no best
                            architecture, only that which is best for your system). Which is of
                            course required for understanding Chapter 4.

                            Chapter 4 considers the problems raised by the WWW, and suggests that
                            the architecture may be improved by applying design-by-constraint to it,
                            in order to address those problems. First, by identifying the desirable
                            properties of the early Web, and the constraints responsible for them;
                            next, by extending that architecture by adding additional constraints,
                            resulting in a new hybrid style consisting of aspects of existing
                            styles. Of course, this is required for understanding Chapter 5.

                            "REST provides a set of architectural constraints that, WHEN APPLIED
                            AS A WHOLE, emphasizes scalability of component interactions, generality
                            of interfaces, independent deployment of components, and intermediary
                            components to reduce interaction latency, enforce security, and
                            encapsulate legacy systems." (4.4)

                            Which brings us to Chapter 5, and the short answer to your question:
                            "POSTing to /cancel violates the Identification of Resources constraint,
                            and is therefore unRESTful." But I've found that just giving that
                            answer tends to upset folks who've only read Chapter 5, then they get
                            defensive about why can't they call their API RESTful, accusations of
                            pedantry follow, and threads devolve into general ugliness, heheh...

                            My point is, you'll have a much harder time trying to understand REST
                            by being told bluntly what is and isn't RESTful, than you will by
                            reading Roy's thesis in its entirety. As computer science dissertations
                            go, Roy produced a functional work of art, much as an Eames chair isn't
                            just a piece of furniture. Understanding what the constraints are, and
                            where they come from, is vital to understanding how they're applied to
                            the Web to derive REST, and why they must be implemented as a whole to
                            achieve REST.

                            Only then will it become apparent when they're being violated, as in
                            the example given of POSTing to an unGETtable /cancel URL. That level
                            of understanding comes from the bottom up, not from the top down, IMO.
                            Knowing what is or isn't REST depends on understanding the pros and
                            cons of various architectural styles, because that's what constraints
                            are, and constraints must be understood before their application to the
                            Web as REST can be understood.

                            More importantly, understanding REST as a style makes one a better
                            architect, because sometimes it's advantageous to deviate from REST's
                            constraints. Which is why I'm always on about how saying something
                            isn't REST is not a value judgment, just a fact. Understanding Roy's
                            thesis allows you to identify the constraints you have applied, and
                            understand that as its own architectural style derived from REST, to
                            use as a guide to developing that system -- but also to understand
                            which desirable properties of REST you're forfeiting in the bargain.

                            Making informed decisions about which constraints to apply, is making
                            use of REST as a tool for long-term development. It may not be
                            feasible to apply all the constraints initially, if REST is truly what
                            your system needs. In which case your system design can account for
                            this, becoming more RESTful over time, instead of painting yourself
                            into a corner where the system needs re-architecting rather than
                            implementing another constraint as an extension.

                            -Eric
                          • Eric J. Bowman
                            ... This is why Roy s thesis is an invaluable tool, at least for me anyway as I ve been at this since 93 and had a front-row seat at the transition from the
                            Message 13 of 28 , Dec 1, 2012
                            • 0 Attachment
                              "Eric J. Bowman" wrote:
                              >
                              > Making informed decisions about which constraints to apply, is making
                              > use of REST as a tool for long-term development. It may not be
                              > feasible to apply all the constraints initially, if REST is truly what
                              > your system needs. In which case your system design can account for
                              > this, becoming more RESTful over time, instead of painting yourself
                              > into a corner where the system needs re-architecting rather than
                              > implementing another constraint as an extension.
                              >

                              This is why Roy's thesis is an invaluable tool, at least for me anyway
                              as I've been at this since '93 and had a front-row seat at the
                              transition from the old Web to HTTP 1.1 -- Roy's experience applying
                              his concepts to a system I was familiar with is included in his thesis,
                              which helped me to incrementally apply REST to my own work as I gained
                              understanding of it. Now, I can confidently design systems today which
                              may be easily extended to be fully RESTful tomorrow.

                              So I really don't stress about the unRESTful aspects of my systems,
                              they're "by design" and will continue to work themselves out over time.
                              Which is exactly what you want from an architectural style, particularly
                              for the Web. Successful websites tend to grow users over time, and it
                              ain't easy to chuck one system for another. What's needed is a system
                              which uses progressively less resources per user, as usage increases.

                              (Just check out the shoddy uptime records of certain big boys on the
                              block to see how badly this desirable property is needed, and note that
                              they don't begin to implement REST.)

                              Using REST as a tool enables the development of such systems by allowing
                              the architect to chart a steady course, deciding which constraints (like
                              identification of resources) are crucial to get right from the get-go,
                              and which may be put off until they satisfy a cost-benefit analysis.

                              For example, most popular CMS software defaults to no-cache. But this
                              doesn't really matter until you're starting to bump into the transfer
                              limits of your hosting plan, at which time you can implement caching,
                              after having some time to test the setup first. You can then fine-tune
                              your cache settings over time, and later integrate with a CDN. This is
                              usually done ad-hoc, what I'm saying is that knowledge of REST can make
                              this go smoothly rather than being a comedy of errors (quite common).

                              If your system doesn't grow to need it, then you can probably do without
                              all the added development expense (plus complexity driving up long-term
                              maintenance costs) of implementing non-native caching on that CMS. REST
                              is your friend when it comes to planning for and managing these expenses
                              and complexities vis-a-vis your cashflow. Budgeting for ho-hum websites
                              is easy; successful websites are another story entirely, where knowledge
                              of REST as a tool can be your competitive edge in funding growth from
                              cashflow instead of debt or outside capital while turning a profit --
                              instead of piling up red ink on wasteful infrastructure.

                              Yeah, I know. That just isn't how things are done on the Web! :-D

                              -Eric
                            • Greg Young
                              /CRMapp?order=1&query=status until intermediaries decide to ignore you because the ? ... They shouldn t but they do :) ... -- Le doute n est pas une condition
                              Message 14 of 28 , Dec 1, 2012
                              • 0 Attachment
                                 /CRMapp?order=1&query=status

                                until intermediaries decide to ignore you because the ?

                                :(

                                They shouldn't but they do :)

                                On Fri, Nov 30, 2012 at 10:56 PM, Eric J. Bowman <eric@...> wrote:
                                /CRMapp?order=1&query=status



                                --
                                Le doute n'est pas une condition agréable, mais la certitude est absurde.
                              • Eric J. Bowman
                                ... They re configurable, and while this may have been a problem in the past, I don t believe it to be anything but an edge case, now. URIs are opaque and
                                Message 15 of 28 , Dec 1, 2012
                                • 0 Attachment
                                  Greg Young wrote:
                                  >
                                  > /CRMapp?order=1&query=status
                                  >
                                  > until intermediaries decide to ignore you because the ?
                                  >
                                  > :(
                                  >
                                  > They shouldn't but they do :)
                                  >

                                  They're configurable, and while this may have been a problem in the
                                  past, I don't believe it to be anything but an edge case, now. URIs
                                  are opaque and should be considered in their entirety as cache keys.
                                  The best a developer can do, is design to REST -- my example certainly
                                  doesn't violate any constraints -- and let the deployed architecture
                                  catch up.

                                  There's much FUD out there about query strings, particularly in REST
                                  discussions, which amounts to unfounded myth. I see no reason to avoid
                                  query strings because they *might* be ignored by a small percentage of
                                  caches, economy of scale still kicks in vs. no-cache. So go ahead and
                                  treat URIs as opaque when doing REST development, the downside is
                                  more than compensated for by the upside, more so as time goes by.

                                  -Eric
                                • Erik Mogensen
                                  This post is mostly aimed at Max Toro, but Eric provided a nice entry point for me :-) ... Exactly. And we don t know what the author intends to identify just
                                  Message 16 of 28 , Dec 1, 2012
                                  • 0 Attachment
                                    This post is mostly aimed at Max Toro, but Eric provided a nice entry point for me :-)

                                    On Sat, Dec 1, 2012 at 8:08 AM, Eric J. Bowman <eric@...> wrote:
                                     

                                    Max Toro wrote:
                                    >
                                    > What I'd love to get is an answer like: POST /orders/1/cancel is not
                                    > REST compliant because chapter x of Fielding's dissertation explicitly
                                    > or implicitly says it's not allowed or it's discouraged. 
                                    >

                                    Well, what are you expecting to GET from /cancel, or are you just using
                                    that URL to invoke a procedure? [...] 
                                     Suggested reading: 6.5.2; 6.2.1, in particular:
                                    "REST [defines] a resource to be the semantics of what the author
                                    intends to identify."

                                    Exactly.  And we don't know what the author intends to identify just by looking at the path /orders/1/cancel.

                                    Just looking at the syntax of a single request (e.g. the method POST and/or the path /orders/1/cancel) is not enough to determine if the system adheres to any particular architectural style.

                                    The author may well intend that /cancel identifies a resource, and allow lots of interaction in it.  It might even have an HTML representation, with a nice <form method="post"><input type="submit" value="CANCEL"></form> in it.

                                    But this is still not enough to determine if a system adheres to the constraints: For even though the server provides such hypermedia controls, media types and does everything "by the book", it is still up to the *client* to actually *use* these hypermedia controls.  In fact it is up to the author of the agent itself.

                                    If you write code in the client that hard wires a button called "cancel" to the "POST /orders/1/cancel" HTTP request then the client isn't really honouring the hypermedia controls laid out above.  If, however, it _soft wires_ the same button _because_ of the hypermedia control above, then you're doing it "more right" I would say.  The point is that the client should be written in such a way that it uses _only_ the hypermedia controls that it receives at run-time.

                                    Roy's thesis really must be considered in its entirety, [...]

                                    +1 to such a degree that 1 > 1.  The rest of the stuff you wrote was great.  I just want to highlight the incorrectness of the question, as others said earlier that REST doesn't say anything about if POST /foo is or isn't...  For all we know /orders/1/cancel is a picture of a dog, or it could be a SOAP endpoint for a nice game of Global Thermonuclear War.

                                    The constraints of REST are too often thought / taught to deal with the server side, but in my experience, it has much more to do with the client side, how much knowledge the client has on things like:

                                    - what URLs can it use? (it shouldn't know any; but bind to one at run-time, preferably via a configuration parameter)
                                    - when it knows one URL (e.g. "/orders/1"), can it add "/cancel" to it to cancel it?  (no, unless it was told to add "/cancel" by a hypermedia control)
                                    - does it know the "type" of a resource, e.g. that /orders/1 is an Order (this is a point of contention on the list; browsers don't know about books or a bank account, but work fine nonetheless.)
                                    - when it does know the type of the URL is an order, does it pull up a pre-coded "order" UI (bad), or does it create a UI based on what it finds in the response (good)


                                    -- 
                                    -mogsie-
                                  • Max Toro
                                    ... To clarify, /orders/1/cancel is used to modify a resource, using POST. A GET request would result in a Method Not Allowed response. This is also explained
                                    Message 17 of 28 , Dec 1, 2012
                                    • 0 Attachment
                                      > Well, what are you expecting to GET from /cancel, or are you just using
                                      > that URL to invoke a procedure? If so, then there are a few places Roy's
                                      > thesis admonishes against it in Chapter 6 -- the rest of REST is about
                                      > positive, rather than negative, reinforcement of the identification of
                                      > resources constraint. Suggested reading: 6.5.2; 6.2.1, in particular:
                                      > "REST [defines] a resource to be the semantics of what the author
                                      > intends to identify."

                                      To clarify, /orders/1/cancel is used to modify a resource, using POST.
                                      A GET request would result in a Method Not Allowed response.

                                      This is also explained on Subbu's book, chapter 2.6 "When and How to
                                      Use Controllers to Operate on Resources":

                                      "Problem: You want to know how to tackle write operations that involve
                                      modifying more than one resource atomically, or whose mapping to PUT
                                      or DELETE is not obvious. Solution: Designate a controller resource
                                      for each distinct operation. Let clients use the HTTP method POST to
                                      submit a request to trigger the operation... If the outcome is the
                                      modification of one or more existing resources, return response code
                                      303 (See Other) with a Location with a URI that clients can use to
                                      fetch a representation of those modifications."

                                      > Not the semantics of a method invocation. What does /cancel identify?
                                      > Sounds to me like a method of tunneling DELETE through POST which
                                      > identifies nothing, iow a procedure endpoint, which is characteristic
                                      > of various styles but not of the REST style. The hypertext constraint
                                      > only makes sense if your resources make sense, in that their URLs are
                                      > identifiers rather than endpoints.

                                      If I understand correctly, you are saying that if I need to affect a
                                      resource then I should use the uniform interface on that resource URI,
                                      and not another URI.

                                      > Which brings us to Chapter 5, and the short answer to your question:
                                      > "POSTing to /cancel violates the Identification of Resources constraint,
                                      > and is therefore unRESTful." But I've found that just giving that
                                      > answer tends to upset folks who've only read Chapter 5, then they get
                                      > defensive about why can't they call their API RESTful, accusations of
                                      > pedantry follow, and threads devolve into general ugliness, heheh...

                                      After reading that chapter again I'm not sure my example violates
                                      anything, but I'd love to get more clarification from you. Is it the
                                      use of a verb in the URI? or not using the URI of the resource I'm
                                      trying to modify directly?
                                      --
                                      Max Toro


                                      On Sat, Dec 1, 2012 at 4:08 AM, Eric J. Bowman <eric@...> wrote:
                                      > Max Toro wrote:
                                      >>
                                      >> What I'd love to get is an answer like: POST /orders/1/cancel is not
                                      >> REST compliant because chapter x of Fielding's dissertation explicitly
                                      >> or implicitly says it's not allowed or it's discouraged. After knowing
                                      >> what is or isn't REST then I'd love to learn more about the pros and
                                      >> cons of different architectural and implementation styles.
                                      >>
                                      >
                                      > Well, what are you expecting to GET from /cancel, or are you just using
                                      > that URL to invoke a procedure? If so, then there are a few places Roy's
                                      > thesis admonishes against it in Chapter 6 -- the rest of REST is about
                                      > positive, rather than negative, reinforcement of the identification of
                                      > resources constraint. Suggested reading: 6.5.2; 6.2.1, in particular:
                                      > "REST [defines] a resource to be the semantics of what the author
                                      > intends to identify."
                                      >
                                      > Not the semantics of a method invocation. What does /cancel identify?
                                      > Sounds to me like a method of tunneling DELETE through POST which
                                      > identifies nothing, iow a procedure endpoint, which is characteristic
                                      > of various styles but not of the REST style. The hypertext constraint
                                      > only makes sense if your resources make sense, in that their URLs are
                                      > identifiers rather than endpoints.
                                      >
                                      > Roy's thesis really must be considered in its entirety, to understand
                                      > the uniform interface constraint (of which identification of resources
                                      > is a sub-constraint). Chapter 1 introduces the notion of applying
                                      > design-by-constraint to networked software architecture, as inspired
                                      > by Eames IIRC. "A style is a named set of constraints on architectural
                                      > elements that induces the set of properties desired of the
                                      > architecture." (4.3)
                                      >
                                      > Chapter 2 defines terminology associated with networked software
                                      > architecture, which is required for understanding Chapter 3, which lays
                                      > out a methodology for evaluating various styles and applies this to
                                      > several examples. Most importantly, Chapter 3 identifies the
                                      > constraints associated with various styles, and describes the properties
                                      > they induce in a system (which may or may not be beneficial or
                                      > detrimental to the system you're designing; remember there is no best
                                      > architecture, only that which is best for your system). Which is of
                                      > course required for understanding Chapter 4.
                                      >
                                      > Chapter 4 considers the problems raised by the WWW, and suggests that
                                      > the architecture may be improved by applying design-by-constraint to it,
                                      > in order to address those problems. First, by identifying the desirable
                                      > properties of the early Web, and the constraints responsible for them;
                                      > next, by extending that architecture by adding additional constraints,
                                      > resulting in a new hybrid style consisting of aspects of existing
                                      > styles. Of course, this is required for understanding Chapter 5.
                                      >
                                      > "REST provides a set of architectural constraints that, WHEN APPLIED
                                      > AS A WHOLE, emphasizes scalability of component interactions, generality
                                      > of interfaces, independent deployment of components, and intermediary
                                      > components to reduce interaction latency, enforce security, and
                                      > encapsulate legacy systems." (4.4)
                                      >
                                      > Which brings us to Chapter 5, and the short answer to your question:
                                      > "POSTing to /cancel violates the Identification of Resources constraint,
                                      > and is therefore unRESTful." But I've found that just giving that
                                      > answer tends to upset folks who've only read Chapter 5, then they get
                                      > defensive about why can't they call their API RESTful, accusations of
                                      > pedantry follow, and threads devolve into general ugliness, heheh...
                                      >
                                      > My point is, you'll have a much harder time trying to understand REST
                                      > by being told bluntly what is and isn't RESTful, than you will by
                                      > reading Roy's thesis in its entirety. As computer science dissertations
                                      > go, Roy produced a functional work of art, much as an Eames chair isn't
                                      > just a piece of furniture. Understanding what the constraints are, and
                                      > where they come from, is vital to understanding how they're applied to
                                      > the Web to derive REST, and why they must be implemented as a whole to
                                      > achieve REST.
                                      >
                                      > Only then will it become apparent when they're being violated, as in
                                      > the example given of POSTing to an unGETtable /cancel URL. That level
                                      > of understanding comes from the bottom up, not from the top down, IMO.
                                      > Knowing what is or isn't REST depends on understanding the pros and
                                      > cons of various architectural styles, because that's what constraints
                                      > are, and constraints must be understood before their application to the
                                      > Web as REST can be understood.
                                      >
                                      > More importantly, understanding REST as a style makes one a better
                                      > architect, because sometimes it's advantageous to deviate from REST's
                                      > constraints. Which is why I'm always on about how saying something
                                      > isn't REST is not a value judgment, just a fact. Understanding Roy's
                                      > thesis allows you to identify the constraints you have applied, and
                                      > understand that as its own architectural style derived from REST, to
                                      > use as a guide to developing that system -- but also to understand
                                      > which desirable properties of REST you're forfeiting in the bargain.
                                      >
                                      > Making informed decisions about which constraints to apply, is making
                                      > use of REST as a tool for long-term development. It may not be
                                      > feasible to apply all the constraints initially, if REST is truly what
                                      > your system needs. In which case your system design can account for
                                      > this, becoming more RESTful over time, instead of painting yourself
                                      > into a corner where the system needs re-architecting rather than
                                      > implementing another constraint as an extension.
                                      >
                                      > -Eric
                                    • Max Toro
                                      Thanks for you answer Erik. I don t want to repeat myself, so please see my answer to Eric, I d love to get your comments as well. Rather than good or bad I d
                                      Message 18 of 28 , Dec 1, 2012
                                      • 0 Attachment
                                        Thanks for you answer Erik. I don't want to repeat myself, so please
                                        see my answer to Eric, I'd love to get your comments as well. Rather
                                        than good or bad I'd like to determine if my example is REST or not.
                                        --
                                        Max Toro


                                        On Sat, Dec 1, 2012 at 10:30 AM, Erik Mogensen <erik@...> wrote:
                                        > This post is mostly aimed at Max Toro, but Eric provided a nice entry point
                                        > for me :-)
                                        >
                                        > On Sat, Dec 1, 2012 at 8:08 AM, Eric J. Bowman <eric@...>
                                        > wrote:
                                        >>
                                        >>
                                        >>
                                        >> Max Toro wrote:
                                        >> >
                                        >> > What I'd love to get is an answer like: POST /orders/1/cancel is not
                                        >> > REST compliant because chapter x of Fielding's dissertation explicitly
                                        >> > or implicitly says it's not allowed or it's discouraged.
                                        >> >
                                        >>
                                        >> Well, what are you expecting to GET from /cancel, or are you just using
                                        >> that URL to invoke a procedure? [...]
                                        >>
                                        >> Suggested reading: 6.5.2; 6.2.1, in particular:
                                        >> "REST [defines] a resource to be the semantics of what the author
                                        >> intends to identify."
                                        >
                                        >
                                        > Exactly. And we don't know what the author intends to identify just by
                                        > looking at the path /orders/1/cancel.
                                        >
                                        > Just looking at the syntax of a single request (e.g. the method POST and/or
                                        > the path /orders/1/cancel) is not enough to determine if the system adheres
                                        > to any particular architectural style.
                                        >
                                        > The author may well intend that /cancel identifies a resource, and allow
                                        > lots of interaction in it. It might even have an HTML representation, with
                                        > a nice <form method="post"><input type="submit" value="CANCEL"></form> in
                                        > it.
                                        >
                                        > But this is still not enough to determine if a system adheres to the
                                        > constraints: For even though the server provides such hypermedia controls,
                                        > media types and does everything "by the book", it is still up to the
                                        > *client* to actually *use* these hypermedia controls. In fact it is up to
                                        > the author of the agent itself.
                                        >
                                        > If you write code in the client that hard wires a button called "cancel" to
                                        > the "POST /orders/1/cancel" HTTP request then the client isn't really
                                        > honouring the hypermedia controls laid out above. If, however, it _soft
                                        > wires_ the same button _because_ of the hypermedia control above, then
                                        > you're doing it "more right" I would say. The point is that the client
                                        > should be written in such a way that it uses _only_ the hypermedia controls
                                        > that it receives at run-time.
                                        >
                                        >> Roy's thesis really must be considered in its entirety, [...]
                                        >
                                        >
                                        > +1 to such a degree that 1 > 1. The rest of the stuff you wrote was great.
                                        > I just want to highlight the incorrectness of the question, as others said
                                        > earlier that REST doesn't say anything about if POST /foo is or isn't...
                                        > For all we know /orders/1/cancel is a picture of a dog, or it could be a
                                        > SOAP endpoint for a nice game of Global Thermonuclear War.
                                        >
                                        > The constraints of REST are too often thought / taught to deal with the
                                        > server side, but in my experience, it has much more to do with the client
                                        > side, how much knowledge the client has on things like:
                                        >
                                        > - what URLs can it use? (it shouldn't know any; but bind to one at run-time,
                                        > preferably via a configuration parameter)
                                        > - when it knows one URL (e.g. "/orders/1"), can it add "/cancel" to it to
                                        > cancel it? (no, unless it was told to add "/cancel" by a hypermedia
                                        > control)
                                        > - does it know the "type" of a resource, e.g. that /orders/1 is an Order
                                        > (this is a point of contention on the list; browsers don't know about books
                                        > or a bank account, but work fine nonetheless.)
                                        > - when it does know the type of the URL is an order, does it pull up a
                                        > pre-coded "order" UI (bad), or does it create a UI based on what it finds in
                                        > the response (good)
                                        >
                                        >
                                        > --
                                        > -mogsie-
                                      • Erik Wilde
                                        hello max. ... i guess most people agree that the only reasonable answer to a question such as is URI X RESTful is: tell me more about your design. i d
                                        Message 19 of 28 , Dec 1, 2012
                                        • 0 Attachment
                                          hello max.

                                          On 2012-12-01 08:17 , Max Toro wrote:
                                          > Thanks for you answer Erik. I don't want to repeat myself, so please
                                          > see my answer to Eric, I'd love to get your comments as well. Rather
                                          > than good or bad I'd like to determine if my example is REST or not.

                                          i guess most people agree that the only reasonable answer to a question
                                          such as "is URI X RESTful" is: "tell me more about your design."

                                          i'd like to get one tiny bit of clarification from you: when saying you
                                          have a resource X/operation, did you choose "cancel" on purpose as
                                          something that could be mapped to a DELETE X fairly easily, or do you
                                          also consider something such as X/additem, where the hypothetical
                                          operation would not delete the resource, but change its status outside
                                          of the CRUD realm?

                                          thanks,

                                          dret.
                                        • Max Toro
                                          Did not choose DELETE because cancel does not delete the resource, it executes some logic which in the end sets it s status field to Canceled. The
                                          Message 20 of 28 , Dec 1, 2012
                                          • 0 Attachment
                                            Did not choose DELETE because cancel does not delete the resource, it
                                            executes some logic which in the end sets it's status field to
                                            Canceled.
                                            The implementation of PATCH with a body 'status=Canceled' can be
                                            tricky if you also accept changes to other fields, which may or may
                                            not have some logic associated to them. I think that using a
                                            subresource as Nicholas Shanks suggested is a good solution, e.g.

                                            PUT /orders/1/status

                                            Canceled

                                            The implementation can do something like this:

                                            switch (value) {
                                            case "Canceled":
                                            cancelOrder(id);
                                            ...
                                            }
                                            --
                                            Max Toro


                                            On Sat, Dec 1, 2012 at 2:58 PM, Erik Wilde <dret@...> wrote:
                                            > hello max.
                                            >
                                            >
                                            > On 2012-12-01 08:17 , Max Toro wrote:
                                            >>
                                            >> Thanks for you answer Erik. I don't want to repeat myself, so please
                                            >> see my answer to Eric, I'd love to get your comments as well. Rather
                                            >> than good or bad I'd like to determine if my example is REST or not.
                                            >
                                            >
                                            > i guess most people agree that the only reasonable answer to a question such
                                            > as "is URI X RESTful" is: "tell me more about your design."
                                            >
                                            > i'd like to get one tiny bit of clarification from you: when saying you have
                                            > a resource X/operation, did you choose "cancel" on purpose as something that
                                            > could be mapped to a DELETE X fairly easily, or do you also consider
                                            > something such as X/additem, where the hypothetical operation would not
                                            > delete the resource, but change its status outside of the CRUD realm?
                                            >
                                            > thanks,
                                            >
                                            > dret.
                                          • Mike Schinkel
                                            ... +1 As an aside you ll find maintenance and validation easier if your status values are all lowercase (all upper would be okay too, but uglier.) Has nothing
                                            Message 21 of 28 , Dec 1, 2012
                                            • 0 Attachment
                                              On Dec 1, 2012, at 9:21 PM, Max Toro <maxtoroq@...> wrote:
                                              > PUT /orders/1/status
                                              > Canceled

                                              +1

                                              As an aside you'll find maintenance and validation easier if your status values are all lowercase (all upper would be okay too, but uglier.)

                                              Has nothing to do with REST, it's just easier to deal with when you don't have to worry what is the proper casing of status values. FWIW.

                                              -Mike
                                            • Matt McClure
                                              ... This seems like a really important point. As I started reading about hypermedia APIs, the authors seemed to be evangelizing the benefit that server
                                              Message 22 of 28 , Dec 2, 2012
                                              • 0 Attachment
                                                On Sat, Dec 1, 2012 at 8:30 AM, Erik Mogensen <erik@...> wrote:
                                                But this is still not enough to determine if a system adheres to the constraints: For even though the server provides such hypermedia controls, media types and does everything "by the book", it is still up to the *client* to actually *use* these hypermedia controls.  In fact it is up to the author of the agent itself.

                                                If you write code in the client that hard wires a button called "cancel" to the "POST /orders/1/cancel" HTTP request then the client isn't really honouring the hypermedia controls laid out above.  If, however, it _soft wires_ the same button _because_ of the hypermedia control above, then you're doing it "more right" I would say.  The point is that the client should be written in such a way that it uses _only_ the hypermedia controls that it receives at run-time.

                                                This seems like a really important point. As I started reading about hypermedia APIs, the authors seemed to be evangelizing the benefit that server programmers could change URIs as requirements evolved. But it seems you can only realize that benefit easily if you can guarantee that all your clients use the hypermedia controls, or that you force the issue by breaking clients that aren't honoring that agreement. Hypermedia APIs seem to raise the expectations on client programmers more than for server programmers.

                                                As a server programmer, I'm interested to find great examples of hypermedia APIs (and ecosystems, documentation, etc.) that help their client programmers do the right thing.

                                                Even then, if you can't prevent client developers from "deep linking" into your API, how do you handle breaking changes for those clients?
                                              • Erik Wilde
                                                hello matt. ... this is a very good question. one important aspect is that it s always bad if clients are tested against just one implementation. server
                                                Message 23 of 28 , Dec 2, 2012
                                                • 0 Attachment
                                                  hello matt.

                                                  On 2012-12-02 08:44 , Matt McClure wrote:
                                                  > Even then, if you can't prevent client developers from "deep linking"
                                                  > into your API, how do you handle breaking changes for those clients?

                                                  this is a very good question. one important aspect is that it's always
                                                  bad if clients are tested against just one implementation. server
                                                  programmers often put quite a bit of effort into designing pretty URIs,
                                                  which is good. but this also lures client programmers into relying on
                                                  those patterns, and as long as you just test against one implementation,
                                                  things often work fine.

                                                  however, often there only is one implementation to test against, so what
                                                  then? something i've been thinking about (and nothing more, and also i
                                                  haven't seen any frameworks supporting this) would be that server
                                                  frameworks could have a "test" switch, that would start serving "ugly"
                                                  and pretty much random URIs, instead of the pretty designed ones. a test
                                                  installation could then be easily provided to client programmers, and
                                                  their code would break very quickly in all places where they took
                                                  shortcuts, instead of following links.

                                                  i haven't seen support for this so far, but it seems to me that in many
                                                  REST-oriented server-side frameworks, this might not be all that hard to
                                                  add. if somebody has seen such a thing in practice, please let me know!

                                                  cheers,

                                                  dret.

                                                  --
                                                  erik wilde | mailto:dret@... - tel:+1-510-2061079 |
                                                  | UC Berkeley - School of Information (ISchool) |
                                                  | http://dret.net/netdret http://twitter.com/dret |
                                                • Eric J. Bowman
                                                  ... DELETE /orders/1 doesn t have to delete the resource, it can move it to, say, /canceled/1. In which case you re only changing one property of the order
                                                  Message 24 of 28 , Dec 3, 2012
                                                  • 0 Attachment
                                                    Max Toro wrote:
                                                    >
                                                    > Did not choose DELETE because cancel does not delete the resource, it
                                                    > executes some logic which in the end sets it's status field to
                                                    > Canceled.
                                                    >

                                                    DELETE /orders/1 doesn't have to delete the resource, it can move it to,
                                                    say, /canceled/1. In which case you're only changing one property of
                                                    the order "object" on your server -- its mapping. REST isn't CRUD. In
                                                    a hypertext API, it's often best to have different URI paths for the
                                                    same set of server objects, if their policies vary based on a property
                                                    like status...

                                                    Web servers configure policies based on path, so add another URI mapping
                                                    instead of making server logic more complex by trying to apply different
                                                    policies based on parsing content for 'canceled=true'. Try to think in
                                                    terms of hypertext applications instead of serializing objects to
                                                    hypertext -- status isn't a field in a hypertext document in REST when
                                                    its semantics overlap that of HTTP status responses, especially if
                                                    status varies by user role:

                                                    The customer checking /orders/1 knows they've successfully canceled it,
                                                    because their DELETE request responded 200 OK with the order and new
                                                    status in the message body, and that URL now responds to GET with 410
                                                    Gone. The 410 response may include the order as its entity, or not,
                                                    for the customer role.

                                                    Other user roles, i.e. admin, may get redirected to /canceled/1, where
                                                    they are subject to different policies than exist for an active order.
                                                    Admins may DELETE from /canceled to actually delete a canceled order,
                                                    while customers are 403 Forbidden from entering /canceled to begin with.
                                                    Also, just because you're using the DELETE method, doesn't mean the UI
                                                    has to say "delete" on the cancel control.

                                                    >
                                                    > The implementation of PATCH with a body 'status=Canceled' can be
                                                    > tricky if you also accept changes to other fields, which may or may
                                                    > not have some logic associated to them.
                                                    >

                                                    What matters is user intent. Clear intention to cancel an order should
                                                    unambiguously be its own operation from the UI-design perspective; from
                                                    the protocol perspective, this idempotent user action should be made
                                                    explicitly visible on the wire by selecting the most appropriate HTTP
                                                    method.

                                                    Of all manipulations we may allow for an order, this is the only one
                                                    that's self-explanatory without transferring a representation, another
                                                    indication that DELETE has the semantics we're after, provided we don't
                                                    get hung up on having to delete something -- which we don't!

                                                    If, to the requesting user, canceling an order makes it go away, then
                                                    using DELETE meets the self-descriptive messaging and uniform interface
                                                    constraints of REST. What happens to the order is an implementation
                                                    detail, hidden behind the uniform interface. To the world-at-large,
                                                    the traffic pattern of an order cancellation looks like exactly what it
                                                    is, as the principle of generality has been followed.

                                                    The visibility of DELETE allows intermediaries to mark cached copies
                                                    of /orders/1 as stale. This optimization is built-in to the deployed
                                                    infrastructure of the Web, all it does here is ensure the requesting
                                                    user doesn't re-load a stale copy of /orders/1 which fails to reflect
                                                    the results of the action just taken. This can't be done with PATCH,
                                                    even if you can get close by marking the request as idempotent.

                                                    -Eric
                                                  • Eric J. Bowman
                                                    ... Yes, such examples are out there, but in them, /cancel is NOT a resource in the REST sense so they must be some style of RPC... REST, not so much.
                                                    Message 25 of 28 , Dec 3, 2012
                                                    • 0 Attachment
                                                      Max Toro wrote:
                                                      >
                                                      > > Well, what are you expecting to GET from /cancel, or are you just
                                                      > > using that URL to invoke a procedure? If so, then there are a few
                                                      > > places Roy's thesis admonishes against it in Chapter 6 -- the rest
                                                      > > of REST is about positive, rather than negative, reinforcement of
                                                      > > the identification of resources constraint. Suggested reading:
                                                      > > 6.5.2; 6.2.1, in particular: "REST [defines] a resource to be the
                                                      > > semantics of what the author intends to identify."
                                                      >
                                                      > To clarify, /orders/1/cancel is used to modify a resource, using POST.
                                                      > A GET request would result in a Method Not Allowed response.
                                                      >

                                                      Yes, such examples are out there, but in them, /cancel is NOT a resource
                                                      in the REST sense so they must be some style of RPC... REST, not so
                                                      much. Representational State Transfer means just that -- resources are
                                                      manipulated by transferring representations of their current, intended,
                                                      desired etc. state. Chapter 5.4:

                                                      "Requests and responses have the appearance of a remote invocation
                                                      style, but REST messages are targeted at a conceptual resource rather
                                                      than an implementation identifier."

                                                      This example is a REST anti-pattern, as I cannot deduce the current
                                                      (sub)state of the order (active or canceled) by dereferencing the URL
                                                      I'm given for manipulating that (sub)state. Just making a toggle POST
                                                      also fails to transfer any representation of anything, let alone
                                                      application state, and isn't proper HTTP (which can never be proper
                                                      REST).

                                                      REST isn't about optimizing upstream traffic, it's about optimizing GET.
                                                      What advantage does a subresource give when it contains no content from
                                                      the parent resource? My goal with subresources is to increase the cache
                                                      stickiness of their parent resources. Replace the subresource content
                                                      in the parent resource, with a link or a hypertext control linked to the
                                                      subresource. The link or hypertext control remains static, and cached,
                                                      as the content of the subresource varies.

                                                      That's a RESTful pattern, as the subresource now has a representation
                                                      (other than that of the 406 error) we can transfer and manipulate to
                                                      effect change of the parent resource.

                                                      >
                                                      > > Not the semantics of a method invocation. What does /cancel
                                                      > > identify? Sounds to me like a method of tunneling DELETE through
                                                      > > POST which identifies nothing, iow a procedure endpoint, which is
                                                      > > characteristic of various styles but not of the REST style. The
                                                      > > hypertext constraint only makes sense if your resources make sense,
                                                      > > in that their URLs are identifiers rather than endpoints.
                                                      >
                                                      > If I understand correctly, you are saying that if I need to affect a
                                                      > resource then I should use the uniform interface on that resource URI,
                                                      > and not another URI.
                                                      >

                                                      Absolutely not! My example changed /order/1 by manipulating /order/1
                                                      /status. The /order/1 resource includes its status, but its 200 OK
                                                      representations only include links to the /status subresource, derived
                                                      from the /order/1 resource such that manipulating a representation
                                                      of /order/1/status updates /order/1 (on the server, you can do anything
                                                      you want; on the client, the cached link/control in /order/1 now returns
                                                      a different value).

                                                      There's no cost to adding a URI like this, nor does it preclude changing
                                                      order status via PUT/PATCH to /order/1. The difference is that /status
                                                      uses REST's uniform interface, unlike /cancel. The /order/1/status URL
                                                      is only presented within a hypertext control which explains how to
                                                      manipulate it -- picture a drop-down list with the current status
                                                      highlighted, meeting the hypertext constraint. You can always GET the
                                                      status of an order even if you don't have a copy of that order, a
                                                      useful separation of concerns beyond just optimizing GET, promoting
                                                      serendipitous re-use.

                                                      >
                                                      > > Which brings us to Chapter 5, and the short answer to your question:
                                                      > > "POSTing to /cancel violates the Identification of Resources
                                                      > > constraint, and is therefore unRESTful." But I've found that just
                                                      > > giving that answer tends to upset folks who've only read Chapter 5,
                                                      > > then they get defensive about why can't they call their API
                                                      > > RESTful, accusations of pedantry follow, and threads devolve into
                                                      > > general ugliness, heheh...
                                                      >
                                                      > After reading that chapter again I'm not sure my example violates
                                                      > anything, but I'd love to get more clarification from you. Is it the
                                                      > use of a verb in the URI? or not using the URI of the resource I'm
                                                      > trying to modify directly?
                                                      >

                                                      The biggest problem, is that an RPC endpoint which has no GET function
                                                      while improperly listening for a method itself as a trigger rather than
                                                      taking action based on the content of the entity required by that method
                                                      and in obeyance of the semantics of that method, is so far away from
                                                      REST that I don't know where to start except by urging that Roy's
                                                      thesis be read in its entirety. Because it's obvious to me that this
                                                      violates the first three uniform interface constraints, making adherence
                                                      to the fourth irrelevant:

                                                      "REST is defined by four interface constraints: identification of
                                                      resources; manipulation of resources through representations; self-
                                                      descriptive messages; and, hypermedia as the engine of application
                                                      state."

                                                      Note that "noun/verb" terminology is not present in the dissertation.
                                                      But, yeah, if your URI is a "verb" you're probably getting REST wrong.
                                                      There is no "cancel" method in the uniform interface. There are two
                                                      basic means of solving this -- one, is refactor your cancel operation
                                                      to use DELETE; two, tunnel your proprietary cancel method through POST.

                                                      http://tech.groups.yahoo.com/group/rest-discuss/message/19210

                                                      Making this operation its own URI doesn't make it more RESTful, as the
                                                      resulting URI is only a resource in the HTTP/URI sense, but not the
                                                      REST sense, of the term. Utilizing subresources to break out more
                                                      dynamic aspects of content and cache them separately is RESTful; if the
                                                      contents of the GET are also allowable content of a PUT then we're
                                                      letting hypertext drive application state instead of listening for POST
                                                      events to trigger server-object methods we've failed to refactor to the
                                                      uniform REST interface.

                                                      -Eric
                                                    • Max Toro
                                                      Thank you very much for your responses Eric. The short answer is (if I understood correctly): POST /cancel is not REST because it lacks visibility, since it s
                                                      Message 26 of 28 , Dec 4, 2012
                                                      • 0 Attachment
                                                        Thank you very much for your responses Eric.

                                                        The short answer is (if I understood correctly): POST /cancel is not
                                                        REST because it lacks visibility, since it's not possible to
                                                        understand the client's intent by examining the request.

                                                        Never thought about HTTP/URI resource vs. REST resource, you say that
                                                        a URI that doesn't implement GET is probably (or always) not REST.
                                                        --
                                                        Max Toro


                                                        On Mon, Dec 3, 2012 at 1:17 PM, Eric J. Bowman <eric@...> wrote:
                                                        > Max Toro wrote:
                                                        >>
                                                        >> > Well, what are you expecting to GET from /cancel, or are you just
                                                        >> > using that URL to invoke a procedure? If so, then there are a few
                                                        >> > places Roy's thesis admonishes against it in Chapter 6 -- the rest
                                                        >> > of REST is about positive, rather than negative, reinforcement of
                                                        >> > the identification of resources constraint. Suggested reading:
                                                        >> > 6.5.2; 6.2.1, in particular: "REST [defines] a resource to be the
                                                        >> > semantics of what the author intends to identify."
                                                        >>
                                                        >> To clarify, /orders/1/cancel is used to modify a resource, using POST.
                                                        >> A GET request would result in a Method Not Allowed response.
                                                        >>
                                                        >
                                                        > Yes, such examples are out there, but in them, /cancel is NOT a resource
                                                        > in the REST sense so they must be some style of RPC... REST, not so
                                                        > much. Representational State Transfer means just that -- resources are
                                                        > manipulated by transferring representations of their current, intended,
                                                        > desired etc. state. Chapter 5.4:
                                                        >
                                                        > "Requests and responses have the appearance of a remote invocation
                                                        > style, but REST messages are targeted at a conceptual resource rather
                                                        > than an implementation identifier."
                                                        >
                                                        > This example is a REST anti-pattern, as I cannot deduce the current
                                                        > (sub)state of the order (active or canceled) by dereferencing the URL
                                                        > I'm given for manipulating that (sub)state. Just making a toggle POST
                                                        > also fails to transfer any representation of anything, let alone
                                                        > application state, and isn't proper HTTP (which can never be proper
                                                        > REST).
                                                        >
                                                        > REST isn't about optimizing upstream traffic, it's about optimizing GET.
                                                        > What advantage does a subresource give when it contains no content from
                                                        > the parent resource? My goal with subresources is to increase the cache
                                                        > stickiness of their parent resources. Replace the subresource content
                                                        > in the parent resource, with a link or a hypertext control linked to the
                                                        > subresource. The link or hypertext control remains static, and cached,
                                                        > as the content of the subresource varies.
                                                        >
                                                        > That's a RESTful pattern, as the subresource now has a representation
                                                        > (other than that of the 406 error) we can transfer and manipulate to
                                                        > effect change of the parent resource.
                                                        >
                                                        >>
                                                        >> > Not the semantics of a method invocation. What does /cancel
                                                        >> > identify? Sounds to me like a method of tunneling DELETE through
                                                        >> > POST which identifies nothing, iow a procedure endpoint, which is
                                                        >> > characteristic of various styles but not of the REST style. The
                                                        >> > hypertext constraint only makes sense if your resources make sense,
                                                        >> > in that their URLs are identifiers rather than endpoints.
                                                        >>
                                                        >> If I understand correctly, you are saying that if I need to affect a
                                                        >> resource then I should use the uniform interface on that resource URI,
                                                        >> and not another URI.
                                                        >>
                                                        >
                                                        > Absolutely not! My example changed /order/1 by manipulating /order/1
                                                        > /status. The /order/1 resource includes its status, but its 200 OK
                                                        > representations only include links to the /status subresource, derived
                                                        > from the /order/1 resource such that manipulating a representation
                                                        > of /order/1/status updates /order/1 (on the server, you can do anything
                                                        > you want; on the client, the cached link/control in /order/1 now returns
                                                        > a different value).
                                                        >
                                                        > There's no cost to adding a URI like this, nor does it preclude changing
                                                        > order status via PUT/PATCH to /order/1. The difference is that /status
                                                        > uses REST's uniform interface, unlike /cancel. The /order/1/status URL
                                                        > is only presented within a hypertext control which explains how to
                                                        > manipulate it -- picture a drop-down list with the current status
                                                        > highlighted, meeting the hypertext constraint. You can always GET the
                                                        > status of an order even if you don't have a copy of that order, a
                                                        > useful separation of concerns beyond just optimizing GET, promoting
                                                        > serendipitous re-use.
                                                        >
                                                        >>
                                                        >> > Which brings us to Chapter 5, and the short answer to your question:
                                                        >> > "POSTing to /cancel violates the Identification of Resources
                                                        >> > constraint, and is therefore unRESTful." But I've found that just
                                                        >> > giving that answer tends to upset folks who've only read Chapter 5,
                                                        >> > then they get defensive about why can't they call their API
                                                        >> > RESTful, accusations of pedantry follow, and threads devolve into
                                                        >> > general ugliness, heheh...
                                                        >>
                                                        >> After reading that chapter again I'm not sure my example violates
                                                        >> anything, but I'd love to get more clarification from you. Is it the
                                                        >> use of a verb in the URI? or not using the URI of the resource I'm
                                                        >> trying to modify directly?
                                                        >>
                                                        >
                                                        > The biggest problem, is that an RPC endpoint which has no GET function
                                                        > while improperly listening for a method itself as a trigger rather than
                                                        > taking action based on the content of the entity required by that method
                                                        > and in obeyance of the semantics of that method, is so far away from
                                                        > REST that I don't know where to start except by urging that Roy's
                                                        > thesis be read in its entirety. Because it's obvious to me that this
                                                        > violates the first three uniform interface constraints, making adherence
                                                        > to the fourth irrelevant:
                                                        >
                                                        > "REST is defined by four interface constraints: identification of
                                                        > resources; manipulation of resources through representations; self-
                                                        > descriptive messages; and, hypermedia as the engine of application
                                                        > state."
                                                        >
                                                        > Note that "noun/verb" terminology is not present in the dissertation.
                                                        > But, yeah, if your URI is a "verb" you're probably getting REST wrong.
                                                        > There is no "cancel" method in the uniform interface. There are two
                                                        > basic means of solving this -- one, is refactor your cancel operation
                                                        > to use DELETE; two, tunnel your proprietary cancel method through POST.
                                                        >
                                                        > http://tech.groups.yahoo.com/group/rest-discuss/message/19210
                                                        >
                                                        > Making this operation its own URI doesn't make it more RESTful, as the
                                                        > resulting URI is only a resource in the HTTP/URI sense, but not the
                                                        > REST sense, of the term. Utilizing subresources to break out more
                                                        > dynamic aspects of content and cache them separately is RESTful; if the
                                                        > contents of the GET are also allowable content of a PUT then we're
                                                        > letting hypertext drive application state instead of listening for POST
                                                        > events to trigger server-object methods we've failed to refactor to the
                                                        > uniform REST interface.
                                                        >
                                                        > -Eric
                                                      • Jan Algermissen
                                                        ... Maybe of interest: http://tech.groups.yahoo.com/group/rest-discuss/message/18998 jan
                                                        Message 27 of 28 , Dec 4, 2012
                                                        • 0 Attachment
                                                          On Dec 4, 2012, at 11:40 PM, Max Toro <maxtoroq@...> wrote:

                                                          > Thank you very much for your responses Eric.
                                                          >
                                                          > The short answer is (if I understood correctly): POST /cancel is not
                                                          > REST because it lacks visibility, since it's not possible to
                                                          > understand the client's intent by examining the request.

                                                          Maybe of interest: http://tech.groups.yahoo.com/group/rest-discuss/message/18998

                                                          jan


                                                          >
                                                          > Never thought about HTTP/URI resource vs. REST resource, you say that
                                                          > a URI that doesn't implement GET is probably (or always) not REST.
                                                          > --
                                                          > Max Toro
                                                          >
                                                          > On Mon, Dec 3, 2012 at 1:17 PM, Eric J. Bowman <eric@...> wrote:
                                                          > > Max Toro wrote:
                                                          > >>
                                                          > >> > Well, what are you expecting to GET from /cancel, or are you just
                                                          > >> > using that URL to invoke a procedure? If so, then there are a few
                                                          > >> > places Roy's thesis admonishes against it in Chapter 6 -- the rest
                                                          > >> > of REST is about positive, rather than negative, reinforcement of
                                                          > >> > the identification of resources constraint. Suggested reading:
                                                          > >> > 6.5.2; 6.2.1, in particular: "REST [defines] a resource to be the
                                                          > >> > semantics of what the author intends to identify."
                                                          > >>
                                                          > >> To clarify, /orders/1/cancel is used to modify a resource, using POST.
                                                          > >> A GET request would result in a Method Not Allowed response.
                                                          > >>
                                                          > >
                                                          > > Yes, such examples are out there, but in them, /cancel is NOT a resource
                                                          > > in the REST sense so they must be some style of RPC... REST, not so
                                                          > > much. Representational State Transfer means just that -- resources are
                                                          > > manipulated by transferring representations of their current, intended,
                                                          > > desired etc. state. Chapter 5.4:
                                                          > >
                                                          > > "Requests and responses have the appearance of a remote invocation
                                                          > > style, but REST messages are targeted at a conceptual resource rather
                                                          > > than an implementation identifier."
                                                          > >
                                                          > > This example is a REST anti-pattern, as I cannot deduce the current
                                                          > > (sub)state of the order (active or canceled) by dereferencing the URL
                                                          > > I'm given for manipulating that (sub)state. Just making a toggle POST
                                                          > > also fails to transfer any representation of anything, let alone
                                                          > > application state, and isn't proper HTTP (which can never be proper
                                                          > > REST).
                                                          > >
                                                          > > REST isn't about optimizing upstream traffic, it's about optimizing GET.
                                                          > > What advantage does a subresource give when it contains no content from
                                                          > > the parent resource? My goal with subresources is to increase the cache
                                                          > > stickiness of their parent resources. Replace the subresource content
                                                          > > in the parent resource, with a link or a hypertext control linked to the
                                                          > > subresource. The link or hypertext control remains static, and cached,
                                                          > > as the content of the subresource varies.
                                                          > >
                                                          > > That's a RESTful pattern, as the subresource now has a representation
                                                          > > (other than that of the 406 error) we can transfer and manipulate to
                                                          > > effect change of the parent resource.
                                                          > >
                                                          > >>
                                                          > >> > Not the semantics of a method invocation. What does /cancel
                                                          > >> > identify? Sounds to me like a method of tunneling DELETE through
                                                          > >> > POST which identifies nothing, iow a procedure endpoint, which is
                                                          > >> > characteristic of various styles but not of the REST style. The
                                                          > >> > hypertext constraint only makes sense if your resources make sense,
                                                          > >> > in that their URLs are identifiers rather than endpoints.
                                                          > >>
                                                          > >> If I understand correctly, you are saying that if I need to affect a
                                                          > >> resource then I should use the uniform interface on that resource URI,
                                                          > >> and not another URI.
                                                          > >>
                                                          > >
                                                          > > Absolutely not! My example changed /order/1 by manipulating /order/1
                                                          > > /status. The /order/1 resource includes its status, but its 200 OK
                                                          > > representations only include links to the /status subresource, derived
                                                          > > from the /order/1 resource such that manipulating a representation
                                                          > > of /order/1/status updates /order/1 (on the server, you can do anything
                                                          > > you want; on the client, the cached link/control in /order/1 now returns
                                                          > > a different value).
                                                          > >
                                                          > > There's no cost to adding a URI like this, nor does it preclude changing
                                                          > > order status via PUT/PATCH to /order/1. The difference is that /status
                                                          > > uses REST's uniform interface, unlike /cancel. The /order/1/status URL
                                                          > > is only presented within a hypertext control which explains how to
                                                          > > manipulate it -- picture a drop-down list with the current status
                                                          > > highlighted, meeting the hypertext constraint. You can always GET the
                                                          > > status of an order even if you don't have a copy of that order, a
                                                          > > useful separation of concerns beyond just optimizing GET, promoting
                                                          > > serendipitous re-use.
                                                          > >
                                                          > >>
                                                          > >> > Which brings us to Chapter 5, and the short answer to your question:
                                                          > >> > "POSTing to /cancel violates the Identification of Resources
                                                          > >> > constraint, and is therefore unRESTful." But I've found that just
                                                          > >> > giving that answer tends to upset folks who've only read Chapter 5,
                                                          > >> > then they get defensive about why can't they call their API
                                                          > >> > RESTful, accusations of pedantry follow, and threads devolve into
                                                          > >> > general ugliness, heheh...
                                                          > >>
                                                          > >> After reading that chapter again I'm not sure my example violates
                                                          > >> anything, but I'd love to get more clarification from you. Is it the
                                                          > >> use of a verb in the URI? or not using the URI of the resource I'm
                                                          > >> trying to modify directly?
                                                          > >>
                                                          > >
                                                          > > The biggest problem, is that an RPC endpoint which has no GET function
                                                          > > while improperly listening for a method itself as a trigger rather than
                                                          > > taking action based on the content of the entity required by that method
                                                          > > and in obeyance of the semantics of that method, is so far away from
                                                          > > REST that I don't know where to start except by urging that Roy's
                                                          > > thesis be read in its entirety. Because it's obvious to me that this
                                                          > > violates the first three uniform interface constraints, making adherence
                                                          > > to the fourth irrelevant:
                                                          > >
                                                          > > "REST is defined by four interface constraints: identification of
                                                          > > resources; manipulation of resources through representations; self-
                                                          > > descriptive messages; and, hypermedia as the engine of application
                                                          > > state."
                                                          > >
                                                          > > Note that "noun/verb" terminology is not present in the dissertation.
                                                          > > But, yeah, if your URI is a "verb" you're probably getting REST wrong.
                                                          > > There is no "cancel" method in the uniform interface. There are two
                                                          > > basic means of solving this -- one, is refactor your cancel operation
                                                          > > to use DELETE; two, tunnel your proprietary cancel method through POST.
                                                          > >
                                                          > > http://tech.groups.yahoo.com/group/rest-discuss/message/19210
                                                          > >
                                                          > > Making this operation its own URI doesn't make it more RESTful, as the
                                                          > > resulting URI is only a resource in the HTTP/URI sense, but not the
                                                          > > REST sense, of the term. Utilizing subresources to break out more
                                                          > > dynamic aspects of content and cache them separately is RESTful; if the
                                                          > > contents of the GET are also allowable content of a PUT then we're
                                                          > > letting hypertext drive application state instead of listening for POST
                                                          > > events to trigger server-object methods we've failed to refactor to the
                                                          > > uniform REST interface.
                                                          > >
                                                          > > -Eric
                                                          >
                                                        • Eric J. Bowman
                                                          ... I d phrase it differently: POST /cancel violates self-descriptiveness as user intent cannot be discerned by examining the request. This would hold true
                                                          Message 28 of 28 , Dec 5, 2012
                                                          • 0 Attachment
                                                            Max Toro wrote:
                                                            >
                                                            > The short answer is (if I understood correctly): POST /cancel is not
                                                            > REST because it lacks visibility, since it's not possible to
                                                            > understand the client's intent by examining the request.
                                                            >

                                                            I'd phrase it differently: "POST /cancel violates self-descriptiveness
                                                            as user intent cannot be discerned by examining the request." This
                                                            would hold true even if GET /cancel had a 200 OK response. Even that's
                                                            oversimplifying in that part of the reason POST is wrong here, is
                                                            because DELETE is right. But, no, I do not believe setting up an URL to
                                                            listen for POST and taking action not based on anything in the POST
                                                            request, is ever an example of the REST style, regardless of the nature
                                                            of the resource.

                                                            My real short answer is, "POST /cancel doesn't use REST's uniform
                                                            interface."

                                                            Neither is it an example of the REST style for POST to have a definition
                                                            which varies by resource, iow sometimes it works without an entity
                                                            (method-tunnel listener), sometimes it doesn't (create resource); even
                                                            if hypertext-driven, such nonstandard method usage inevitably results
                                                            in coupling between client and server, instead of relying on shared
                                                            understanding of standardized method semantics. Fixing the POST to have
                                                            an entity that's ignored might make it valid HTTP and solve this, but it
                                                            still wouldn't be an example of the REST style, where the requested
                                                            state change is transferred in the entity (with a few exceptions) -- not
                                                            defined per resource by the method being tunneled through / triggered by
                                                            POST.

                                                            Conceptually, it still violates the identification of resources
                                                            constraint, which is why it isn't visible regardless of how we implement
                                                            it in terms of hypertext or method selection. Using the uniform
                                                            interface means refactoring internal methods like 'cancel' to fit the
                                                            resource/representation model of REST such that the request methods and
                                                            response codes used map generically to those of your chosen protocol.
                                                            Assigning them URIs to toggle with semantically-void messages is simply
                                                            some other style not encompassed by REST's uniform interface constraint,
                                                            not something that's superficially fixable by improving visibility or
                                                            adding a 200 OK response.

                                                            >
                                                            > Never thought about HTTP/URI resource vs. REST resource, you say that
                                                            > a URI that doesn't implement GET is probably (or always) not REST.
                                                            >

                                                            More like, "REST resources are concepts, not actions." Just using URIs
                                                            doesn't bestow compliance with the identification of resources
                                                            constraint upon a system, it's more nuanced than that. I can't imagine
                                                            why a bona-fide REST resource would ever deliberately fail to have a
                                                            retrieval mapping, no.

                                                            I think the more important takeaway is method selection. We have DELETE
                                                            in order to avoid such convoluted POST-based cancel mechanisms. It
                                                            isn't RESTful to use POST when another method's semantics happen to
                                                            closely describe user intent. From Roy's blog:

                                                            "POST only becomes an issue when it is used in a situation for which
                                                            some other method is ideally suited: e.g., retrieval of information
                                                            that should be a representation of some resource (GET), complete
                                                            replacement of a representation (PUT), or any of the other standardized
                                                            methods that tell intermediaries something more valuable than 'this may
                                                            change something.' The other methods are more valuable to
                                                            intermediaries because they say something about how failures can be
                                                            automatically handled and how intermediate caches can optimize their
                                                            behavior. POST does not have those characteristics, but that doesn't
                                                            mean we can live without it. POST serves many useful purposes in HTTP,
                                                            including the general purpose of 'this action isn't worth
                                                            standardizing.'"

                                                            http://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post

                                                            Since DELETE is inherently self-descriptive of user intent to cancel an
                                                            order, and is already "listened for" rather than requiring an entity be
                                                            transferred, and has inherent idempotency matching the inherently
                                                            idempotent user intent captured by a cancel request, DELETE must be the
                                                            proper method for implementation using HTTP.

                                                            Now, maybe your media type doesn't support DELETE, in which case
                                                            contriving a /cancel URI may very well be called for until such time
                                                            as it does. I won't fault anyone for doing this out of pragmatism, so
                                                            long as they understand it as a mismatch, inconsistent with the
                                                            architectural style they're following.

                                                            REST is a tool which allows you, over time, to make improvements to the
                                                            architecture you have in accordance with an idealized model. To me,
                                                            accepting mismatches for what they are, is far more useful than coming
                                                            up with convoluted explanations for why they aren't, for the sake of
                                                            buzzword compliance. Change is easier when it's based on having been
                                                            right all along, rather than based on having to admit error. ;-)

                                                            -Eric
                                                          Your message has been successfully submitted and would be delivered to recipients shortly.