PUT and idempotency

275 views
Skip to first unread message

miqui

unread,
Jul 26, 2018, 1:46:18 AM7/26/18
to API Craft
hi folks,

 If you invoke a PUT API N times, very first request will update the resource; then rest N-1 requests will just overwrite the same resource state again and again – effectively not changing anything. Hence, PUT is idempotent.

Ok, what if the resource is a back account? ..and the PUT is updating its balance? (i am obviously changing the account)

rgds,
Miguel

Richard Mateosian

unread,
Jul 26, 2018, 2:52:04 PM7/26/18
to api-...@googlegroups.com
If you mean you're sending a new value, that's a new PUT, and it's idempotent. 

If you mean you're sending a remote call to a backend procedure that updates the balance, that's not idempotent, but it's not really a REST API anymore.   ...RM

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at https://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/d/optout.


--

Richard Mateosian <x...@pacbell.net>
Berkeley, California

Jørn Wildt

unread,
Jul 27, 2018, 6:13:30 AM7/27/18
to api-...@googlegroups.com
If you mean you're sending a new value, that's a new PUT, and it's idempotent. 

Yep. It is although hardly a good idea to "set" a bank account's value to anything.

> If you mean you're sending a remote call to a backend procedure that updates the balance, that's not idempotent, but it's not really a REST API anymore.

Well, REST != CRUD ... you can certainly have ressources on the web that allows the client to POST a request for an action to happen - for instance requesting that a certain value is added to a bank account.

You could in principle use PUT - but in that case I would suggest PUT'ing a new *entry* to the account (not the final value of the account), using a GUID in the URL as the unique ID of the entry, allowing the server to recognize multiple attempts to PUT the same entry. In this domain I would expect to be able to GET the same entry again on the same URL, but neither be able to DELETE it nor POST or PATCH changes to it.

/Jørn


On Thu, Jul 26, 2018 at 8:51 PM, Richard Mateosian <xrm...@gmail.com> wrote:
If you mean you're sending a new value, that's a new PUT, and it's idempotent. 

If you mean you're sending a remote call to a backend procedure that updates the balance, that's not idempotent, but it's not really a REST API anymore.   ...RM
On Wed, Jul 25, 2018 at 10:46 PM miqui <migm...@gmail.com> wrote:
hi folks,

 If you invoke a PUT API N times, very first request will update the resource; then rest N-1 requests will just overwrite the same resource state again and again – effectively not changing anything. Hence, PUT is idempotent.

Ok, what if the resource is a back account? ..and the PUT is updating its balance? (i am obviously changing the account)

rgds,
Miguel

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+unsubscribe@googlegroups.com.
--

Richard Mateosian <x...@pacbell.net>
Berkeley, California

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+unsubscribe@googlegroups.com.

Lukas Rosenstock

unread,
Jul 27, 2018, 7:03:20 AM7/27/18
to api-...@googlegroups.com
Hello Miguel,

a PUT is replacing a resource with the version sent from the client. It therefore behaves like idempotent only if you are the only client capable of updating said resource.
If someone else changed the resource in the meantime your PUT reverts it back to your version.

Lukas Rosenstock


--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.

miqui

unread,
Aug 1, 2018, 8:47:22 AM8/1/18
to API Craft
hi Richard,

just thinking of PUT /account/123
{
   "deposit: "100.0"
}

.i am not working on the implementation, just design... so was wondering ... if this operation was idempotent in regards to the context of the bank account being updated..

..but i believe a PATCH would apply here since we are doing a partial update of the account

..thanks for your feedback

miqui

unread,
Aug 1, 2018, 8:53:02 AM8/1/18
to API Craft
.thanks for your feedback..


>>Yep. It is although hardly a good idea to "set" a bank account's value to anything.

Agreed..but can you elaborate why? 

rgds,
Miguel


On Friday, July 27, 2018 at 6:13:30 AM UTC-4, Jørn Wildt wrote:
If you mean you're sending a new value, that's a new PUT, and it's idempotent. 

Yep. It is although hardly a good idea to "set" a bank account's value to anything.

> If you mean you're sending a remote call to a backend procedure that updates the balance, that's not idempotent, but it's not really a REST API anymore.

Well, REST != CRUD ... you can certainly have ressources on the web that allows the client to POST a request for an action to happen - for instance requesting that a certain value is added to a bank account.

You could in principle use PUT - but in that case I would suggest PUT'ing a new *entry* to the account (not the final value of the account), using a GUID in the URL as the unique ID of the entry, allowing the server to recognize multiple attempts to PUT the same entry. In this domain I would expect to be able to GET the same entry again on the same URL, but neither be able to DELETE it nor POST or PATCH changes to it.

/Jørn

On Thu, Jul 26, 2018 at 8:51 PM, Richard Mateosian <xrm...@gmail.com> wrote:
If you mean you're sending a new value, that's a new PUT, and it's idempotent. 

If you mean you're sending a remote call to a backend procedure that updates the balance, that's not idempotent, but it's not really a REST API anymore.   ...RM
On Wed, Jul 25, 2018 at 10:46 PM miqui <migm...@gmail.com> wrote:
hi folks,

 If you invoke a PUT API N times, very first request will update the resource; then rest N-1 requests will just overwrite the same resource state again and again – effectively not changing anything. Hence, PUT is idempotent.

Ok, what if the resource is a back account? ..and the PUT is updating its balance? (i am obviously changing the account)

rgds,
Miguel

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
--

Richard Mateosian <x...@pacbell.net>
Berkeley, California

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.

Jørn Wildt

unread,
Aug 1, 2018, 9:02:35 AM8/1/18
to api-...@googlegroups.com
>>Yep. It is although hardly a good idea to "set" a bank account's value to anything.

> Agreed..but can you elaborate why? 

Because I have a hard time imagining a bank allowing any client to set the bank account directly. I would expect the clients to send a request for adding a deposit.

/Jørn


Philippe Mougin

unread,
Aug 1, 2018, 11:41:27 AM8/1/18
to api-...@googlegroups.com
Hi,

I see a couple of problems here breaking your API. 

First, along with a PUT you must transfer a representation of the desired new state your target resource. This isn’t the case in your example as you are not sending something describing the state of a bank account, but the description of an operation to be carried on this bank account. This is invalid with regard to the HTTP specification.

Second, as you are sending an order of deposit, it is not idempotent by definition, since multiple identical PUT will result in multiple deposits, adding 100 to the balance of the account each time. This also break the HTTP spec (PUTs must be idempotent). 

Best,

Philippe Mougin

Eric Johnson

unread,
Aug 1, 2018, 1:52:39 PM8/1/18
to API Craft
As others on this thread have pointed out, PUT of a bank account balance is almost certainly a design mistake.

Banks track transactions and practice double-entry book-keeping, which has as a side-effect updating the bank account balance. A single "PUT" operation to update the balance violates accounting best-practices, and so is likely a mismatch with your domain.

Instead of "PUT" of the bank account balance, PUT/POST a transaction - for example, to debit the account $100, and transfer the money (to where?). That "transaction" could be something updated with a RESTful PUT, but once the bank has finalized the transaction, any PUT that changes the transaction will almost certainly need to be rejected - at least to be consistent with the problem domain of "banking".

Eric.

Erik Wilde

unread,
Aug 1, 2018, 2:05:49 PM8/1/18
to api-...@googlegroups.com
hello.

On 2018-08-01 10:52, 'Eric Johnson' via API Craft wrote:
> As others on this thread have pointed out, PUT of a bank account balance
> is almost certainly a design mistake.

+100

the balance is read-only, everything else sounds like a terrible idea.

you post transactions, which then will reflect in the balance.

just like in the real world: you don't walk up to the bank and grab some
money and then update the balance yourself. your interaction with the
bank is to deposit or withdraw money. the balance is read-only and might
have some delay updating, depending on how transactions clear.

cheers,

dret.

--
erik wilde | mailto:erik....@dret.net |
| http://dret.net/netdret |
| http://twitter.com/dret |

Carl Zetie

unread,
Aug 3, 2018, 8:02:11 AM8/3/18
to API Craft
+1000

More generally: I've found that whenever I face this kind of problem with an API design, and I'm struggling to define idempotent PUTs, it's a strong indicator that I don't properly understand the domain and / or I haven't correctly identified the entities (in this case, transactions, rather than accounts or deposits).

regards,
--CZ
Reply all
Reply to author
Forward
0 new messages