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

Re: [rest-discuss] PUT or POST, idempotent for the application

Expand Messages
  • mike amundsen
    i d consider modeling it like this: -- create a new (inactive) request C: POST http://example.org/Factory S: HTTP 200 with document
    Message 1 of 4 , Jul 5, 2007
      i'd consider modeling it like this:

      -- create a new (inactive) request
      C: POST http://example.org/Factory <newItemReq />
      S: HTTP 200 with <itemReq /> document and Location:http://example.org/Item/1

      -- activate existing request
      C: HTTP PUT to http://example.org/Item/1 containing modified <itemReq
      /> that has the activate information
      S: HTTP 200 OK.
      S: HTTP 404 Not Found (for invalid request ids)
      S: HTTP 410 Gone (for expired/lost requests)

      mamund

      > (phase 1: tentative)
      > C: HTTP PUT to http://example.org/Factory containing <newItemReq />
      > S: HTTP 201 with Location: http://example.org/Item/1
      >
      > (phase 2: activation)
      > C: HTTP PUT to http://example.org/Item/1 containing <resActivator />
      > S: HTTP 200 OK.

      <snip>
      On 7/5/07, Bruno Harbulot <Bruno.Harbulot@...> wrote:
      > Hello,
      >
      >
      > Apologies if I revive last week's thread about POST being idempotent or
      > not, but it got me confused on the choice between using POST or PUT in
      > the system on which I'm working, and idempotent messages matter in this
      > case.
      >
      </snip>
    • Mike Dierken
      When you use PUT, the URI sent in the request is the identifier of the content within that message. So doing the following would replace the factory with a
      Message 2 of 4 , Jul 5, 2007
        When you use PUT, the URI sent in the request is the identifier of the
        content within that message.
        So doing the following would replace the 'factory' with a 'newItem' blob:
        C: HTTP PUT to http://example.org/Factory containing <newItemReq />

        One difference between PUT and POST is that with PUT the client already
        knows the intended URI (the 'id') of the data being submitted. With POST,
        the server might create a new identifier for the submitted data and the
        clients needs to receive the response to learn what that identifier is.

        In order to activate the resource (acknowledge to the server that the client
        received the response) you are sending a PUT to the new resource with a
        particular content type. Sending different content types via PUT gives rise
        to really long discussion threads on rest-discuss and I generally avoid
        that.

        Perhaps you could request a new blank resource be created via a POST to the
        factory, then populate that blank resource via a PUT with the actual content
        to be stored - this initializing PUT on a blank resource would be idempotent
        so simple retries would help get past some network failures. If the factory
        POST didn't work, the client can retry but a different identifier would be
        created in that case - which is similar to how your design allows for
        un-acknowledged resouces to fade away and similar to what Mike Amundsen
        suggested as well.




        > -----Original Message-----
        > From: rest-discuss@yahoogroups.com
        > [mailto:rest-discuss@yahoogroups.com] On Behalf Of Bruno Harbulot
        > Sent: Thursday, July 05, 2007 11:48 AM
        > To: rest-discuss@yahoogroups.com
        > Subject: [rest-discuss] PUT or POST, idempotent for the application
        >
        > Hello,
        >
        >
        > Apologies if I revive last week's thread about POST being
        > idempotent or not, but it got me confused on the choice
        > between using POST or PUT in the system on which I'm working,
        > and idempotent messages matter in this case.
        >
        >
        > We've designed a system (which I believe complies with the REST
        > principles) that relies on a client interacting with a
        > resource to create other resources.
        >
        >
        > To summarise how this system works, a client can ask the
        > Factory resource to create Item resources. The process of
        > creating an Item resource must follow two constraints:
        > - at the end of the process, the client must have created
        > one Item resource and must know its URI;
        > - at the end of the process, the Factory resource must
        > know that the client knows the new Item resource URI.
        >
        > Initially, we assume the client has been configured to know
        > the URI of the Factory: http://example.org/Factory.
        >
        > The protocol we use is as follows (the numbers in the URIs are just
        > examples):
        >
        > (phase 1: tentative)
        > C: HTTP PUT to http://example.org/Factory containing <newItemReq />
        > S: HTTP 201 with Location: http://example.org/Item/1
        >
        > (phase 2: activation)
        > C: HTTP PUT to http://example.org/Item/1 containing <resActivator />
        > S: HTTP 200 OK.
        >
        >
        > An HTTP GET on http://example.org/Factory returns a list of
        > all the Items that have been created and 'activated' (i.e. of
        > which the Factory knows that the client knows their address).
        > If the Factory never receives the second PUT, the Item
        > resource is not the list document. (Optionally, if the client
        > interacts later with the Item resource, this may activate
        > this resource anyway). Item resources that are not activated
        > may be discarded at any time by the Factory (in which case
        > the client would have to re-start the entire process.)
        >
        > Here is an example of what could go wrong and how this would
        > be handled:
        >
        > (phase 1: tentative)
        > C: HTTP PUT to http://example.org/Factory containing <newItemReq />
        > S: HTTP 201 with Location: http://example.org/Item/1
        > - the connection is lost and the new URI never reaches the client.
        >
        > (phase 1: another attempt)
        > C: HTTP PUT to http://example.org/Factory containing <newItemReq />
        > S: HTTP 201 with Location: http://example.org/Item/2
        >
        > (phase 2: activation)
        > C: HTTP PUT to http://example.org/Item/2 containing <resActivator />
        > S: HTTP 200 OK.
        > - the client knows the URI of the Item it has successfully
        > created, and the factory knows that the client knows.
        >
        >
        >
        > The 'activation' PUT is idempotent because sending it N+1
        > times has the
        > same effect as sending it just once.
        >
        > I also think the first 'tentative' PUT is idempotent, although it is
        > more subtle. Effectively, whatever the URI returned in the tentative
        > phase is does not matter, either to the client or to the
        > factory. When
        > taking into account the two phases, sending N+1 'tentative' PUT + an
        > 'activation' has the same result as sending only one tentative PUT
        > followed by an activation: only one Item resource is
        > activated and both
        > the client and the server know about its URI.
        >
        >
        > When reading Section 9.5 and 9.6 of RFC 2616, my use of PUT
        > here is not
        > appropriate, and it should probably be POST, in both cases, for two
        > different reasons:
        > - the 'tentative' PUT clearly does not comply with "the
        > URI in a PUT
        > request identifies the entity enclosed with the request" (in
        > Section 9.6);
        > - the 'activation' PUT might rather be considered as an
        > "annotation
        > of existing resources" (in Section 9.5).
        >
        >
        >
        > I'm tempted to change these two PUTs into POSTs. However, I
        > quite like
        > the fact that PUT is intended to be idempotent. I believe the
        > fact that
        > a request is guaranteed to be idempotent is more important
        > than "the URI
        > in a PUT request identifies the entity enclosed with the
        > request" when
        > designing distributed systems.
        > Obviously, the use of POST in this system may be idempotent, but it
        > appears to me that it's a constraint that deserves to be given more
        > importance, by using PUT. (By the way, to refer to last
        > week's thread,
        > my understanding of POST not being idempotent is that N+1
        > times the same
        > request may or may not have the same effect as just one.)
        >
        >
        > I'm not sure which one is right between PUT and POST (in both cases),
        > although I tend to think at least the 'tentative' PUT ought to be a
        > POST. Any comments appreciated.
        >
        >
        > Best wishes,
        >
        >
        > Bruno.
        >
        >
        >
        > Yahoo! Groups Links
        >
        >
        >
      • A. Pagaltzis
        Hi Bruno, ... See http://bitworking.org/news/201/RESTify-DayTrader Short answer: the client POSTs a request, upon which the server creates a ticket of the form
        Message 3 of 4 , Jul 6, 2007
          Hi Bruno,

          * Bruno Harbulot <Bruno.Harbulot@...> [2007-07-05 20:50]:
          > I'm tempted to change these two PUTs into POSTs. However, I
          > quite like the fact that PUT is intended to be idempotent. I
          > believe the fact that a request is guaranteed to be idempotent
          > is more important than "the URI in a PUT request identifies the
          > entity enclosed with the request" when designing distributed
          > systems.
          > Obviously, the use of POST in this system may be idempotent,
          > but it appears to me that it's a constraint that deserves to be
          > given more importance, by using PUT. (By the way, to refer to
          > last week's thread, my understanding of POST not being
          > idempotent is that N+1 times the same request may or may not
          > have the same effect as just one.)
          >
          > I'm not sure which one is right between PUT and POST (in both cases),
          > although I tend to think at least the 'tentative' PUT ought to be a
          > POST. Any comments appreciated.

          See http://bitworking.org/news/201/RESTify-DayTrader

          Short answer: the client POSTs a request, upon which the server
          creates a ticket of the form

          {$uuid}:{sha1(concat($uuid,$some_secret))}

          The response contains this ticket in the Location of the form

          http://example.org/Item/{$ticket}

          which the client is expected to PUT to.

          Validating such a ticket relies on knowing the secret only, so
          the server can do it without the necessity for any per-ticket
          storage.

          You could use GET with this scheme if you really wanted to make
          the first request idempotent, but then I’d worry about broken
          intermediaries that might cache the response despite any number
          of headers to the contrary. POST provides an easy reliable way
          to pierce caches.

          Regards,
          --
          Aristotle Pagaltzis // <http://plasmasturm.org/>
        Your message has been successfully submitted and would be delivered to recipients shortly.