I wasn't aware of the distinction between “safe” and “idempotent”, TIL, thank you.
> DELETE is not defined to be safe but it is defined to be idempotent
This one puzzles me though. How can DELETE be idempotent? If the first request works then the second one should return a 404, as the key to delete doesn't exist anymore.
Response is implementation detail: a 404 on second request is one way to do it, a 202 would be another, or 200 with some sort of response to distinguish (e.g. { changed: boolean }).
Idempotency just means no state mutation on subsequent request.
HTTP requests are not RPC calls. The end state of a DELETE request is that the resource does not exist. If you make the request once, the end result is that the resource does not exist. If you make the request twice, the end result is that the resource does not exist. The spec. allows for the actual response to differ; the important thing is that the state is the same regardless.