2

In REST APIs a PUT request is meant to be an idempotent action - the result should always be the same, regardless of what the initial state was.

However, often resources will have attributes like 'created_on', 'last_updated', which I assume are applied by the database. (A client shouldn't be able to determine their own 'last_updated' value, surely).

So in this scenario - is accepted that some values on the resource won't be idempotent? Is there a rule of thumb or a principle that applies?

2
  • Well, logically the created date can't change, otherwise the method would not be idempotent. As for last updated, there is no reason this should necessarily change as a result of repeated requests - if there is no change in the basic data, you wouldn't usually expect the last updated field to change.
    – Steve
    May 6, 2022 at 6:53
  • If you have two requests to create an identical item, and the first one is dropped for some reason, then you have a different creation date.
    – gnasher729
    May 6, 2022 at 7:43

5 Answers 5

5

It is still idempotent as long as the intended effect is the same. It other words, if you can "blindly" repeat the request and it still means the same thing, it is idempotent.

The specification linked above explicitly says that this concept was created for error recovery, that is, to be able to repeat the request. It also specifically mentions logging, version control and other possible side-effects that would not necessarily violate idempotency. I would note, that the intended effect is subjective and can not be described purely technically. It depends on what the request means.

4

Strictly speaking its no longer idempotent, but also things like writing a log make it non-idempotent.

Generally the level of strictness you are expected to apply is:

"If multiple requests are sent in error, the system will still run as designed"

So no errors thrown, no multiple copies of the object on your database, no multiple emails sent etc etc

1

The idempotency concept of a REST API is meant to describe the API design in isolation of any integration with other systems that change the state of the target object. It is meant for the developer to examine that their coding of the API is fault tolerant. But it does not proscribe a limitation on your integration requirements with other systems.

In your example, the “last_updated” value on the resource is updated by a function outside of your API design specs. It was updated by a database trigger or a similar back-end business layer logic. If that business layer logic were to be disabled and you were to repeat your API PUT request, then if the PUT request is repeatable and fault tolerant then it is idempotent.

1

PUT operations are obviously only idempotent if they store the same data.

By having a “last updated” variable, you implicitly add the time of the put request to the arguments, so that wouldn’t be idempotent, and that is fine. Less obviously if you had a “last changed” variable: If you send two identical put requests, and the first one gets lost for some reasons, your “last changed” will have a different value.

What is actually meant by idempotent is that put requests shouldn’t have something like “increase x by 1”, which gives different results when run twice.

0

In REST APIs a PUT request is meant to be an idempotent action - the result should always be the same, regardless of what the initial state was.

Idempotent is not a constraint on the implementation of the request handler, it's a constraint on the semantics of the request (what does the request mean).

Roy Fielding, writing on a similar question in 2002:

HTTP does not attempt to require the results of a GET to be safe. What it does is require that the semantics of the operation be safe, and therefore it is a fault of the implementation, not the interface or the user of that interface, if anything happens as a result that causes loss of property

The classic case for this is an expensive business activity triggered by an HTTP GET request; it's all "fine" right up until some web crawler comes along and tries to index your API.

Analogously, if your attempt to store metadata produces some catastrophe, then the responsibility lies with you, not the caller.

That said, it's really hard to imagine a circumstance where updated metadata is going to befall some disaster, so it's probably fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.