A recent article on InfoQ raised the question of what is idempotence in REST services. A definition for an idempotent service is that the result of successfully performed operation is independent of the number of times it is executed.
For example, typically a read operation is idempotent. Asking for a bank balance will give the same value each time you do it with no side-effects (until another operation changes the bank balance). This would be implemented as GET request in HTTP.
When we consider write operations, an operation to add £10 to a bank balance is not idempotent since each call would increase the value. This is analogous with the POST method in HTTP. It adds to the resource.
Instead, if the operation was to set the balance to a specific value then it could be idempotent. It can be repeated and any successful operation would result in the same post conditions: the balance would be set to the required value. In HTTP terms, this is where the PUT method is used. It sets the value of the resource to be the specified value.
For the purposes of this article we'll ignore the issue that someone else may have changed the value behind the scenes, that can be solved with some form of optimistic locking – the definition of idempotence talks about 'successfully performed operations'.
So the GET and PUT operations may be considered idempotent. However, operationally they probably wouldn't be actually idempotent. If executed multiple times they may result in hidden side-effects. It will probably add to the systems logs and audit records, it could set the 'last accessed' timestamp or in the case of the PUT operation the 'last updated' timestamp etc.
So are these operations idempotent?
Let's consider two subtly different services, both set the value of the account balance to a particular value.
In the first one, when the account balance is set, a new account statement line is created showing the details of the transaction. The client can query the account statement to show the account owner the transactions on their account.
In the second one, when the account balance is set, a new audit record is created showing the details of the transaction. The client can't view audit record, they are stored for operational (and probably legal and compliance) reasons.
Ultimately, what's the difference? Both of these operations result in side-effects, they both update the operational data set. Is the 'audit record' that much different from an 'account statement'?
In the purest sense of the word these services are not idempotent.
However, we want to provide useful services to our clients.
In my mind the importance of idempotence for REST services is in terms of the contract with the client.
If the client can repeatedly and safely call a service, with no effective side-effects as far as their interface to the resource is concerned then it can be considered idempotent. The important distinction for these services is the “no effective side-effects” part.
The first operation could be called repeatedly and safely as far the integrity of the account is concerned, but since it does show a side-effect to the client in the account statement then it can't be considered idempotent. As a REST service, it should be implemented as POST request.
The second operation however is effectively idempotent as far as the client is concerned. There is nothing exposed through the client's interface to show any side-effect for their operation. It can be safely implemented as a PUT service.
Why would we care?
Technically, the difference is pretty subtle. However, it makes a big difference to the client.
If the client knows that the operation has no effective side-effects then it knows it can safely retry it in the event of a failure such as a networking problem. If the service may have side-effects, then the client must do something else to determine if it's safe to retry, such as querying the account to see if the first operation succeeded or not, before trying again.
Therefore, even though operationally, these services can't be considered idempotent, for the purposes of providing useful and well-behaved services to the client it makes sense to say that they are.