Idempotency
The Crunchy Bridge API makes an effort to provide idempotent operations and primitives. Idempotency is a property of an operation dictating that it's possible to safely retry that operation multiple times getting back the same result each time, and without having produced any additional side effects in the system.
Idempotent HTTP verbs
The HTTP specification dictates that the verbs GET
, PUT
, and DELETE
are
inherently idempotent. The Crunchy Bridge API respects those guidelines, and
it's safe to retry operations using these verbs any number of times with no
additional considerations.
DELETE
semantics
Most APIs implement idempotency on DELETE
by simply returning a
404 Not found
for a deleted object after an initial successfully processed
request. This can be somewhat inconvenient for clients because it makes it
impossible for them to distinguish between a deletion that previously executed
versus one targeting an object that never existed in the first place.
As a small convenience feature, the Crunchy Bridge API will return 410 Gone
for objects which have already been deleted, and the standard 404 Not found
for objects which are completely unknown.
Idempotency keys
The POST
and PATCH
verbs are notably not idempotent, so some additional work
is needed to make their use idempotent safe.
The Crunchy Bridge API will accept an Idempotency-Key
header from clients
containing a UUID value which uniquely identifies a request from their end. In
the event of an interrupted transmission or other problem, the client can resend
the request with the same value in Idempotency-Key
and depending on where the
previous request was lost, the API will either process it for the first time, or
send back the stored response of when it was initially processed. The use of
Idempotency-Key
has the effect of making non-idempotent POST
and PATCH
safe for idempotent use.
For example:
-
A client tries to create a cluster by sending
POST /clusters
along with an idempotency key, but the request is terminated before reaching Crunchy's servers. The client retries with the same key. This time the request is successful, the API processes it, and sends back a normal response. -
A client tries to create a cluster by sending
POST /clusters
along with an idempotency key. The API processes the request, but the connection breaks as a response is being sent back to the client. The client retries with the same key. The API notes that this request has already been processed and sends back a stored response. Notably, a second cluster is not created accidentally.
Hint
Although idempotency keys are only used by the API for POST
and PATCH
requests, it's safe to send them along with any verb. A robust client can
integrate idempotency keys simply by sending the Idempotency-Key
field along
with every API request. Combined with a mechanism to retry on failure, this
provides an easy way to create an extremely resilient integration.
Subsequent requests made with the same idempotency key must have the same HTTP
verb, path, and body payload as the original request made with that key. If a
new request doesn't match, the API will respond with a 409 Conflict
and a
message explaining the problem. A 409 Conflict
will also be produced if an
idempotency key is reused before the original request attached to it has had a
chance to finish.
Along with storing the results of successful requests, idempotency keys will
store the results of most unsuccessful ones as well. An initial
400 Bad request
will produce the same result when its key is reused. There are
a few exceptions to this rule where errors are considered to be transitory:
429 Too many requests
(rate limited), 500 Internal server error
, and
503 Service unavailable
. Retrying any of these with the same key will prompt
the API to try the operation again.
Idempotency keys have a server-side lifetime of one hour. Reusing keys after that horizon will have the effect of triggering a brand new request.
Idempotency keys must be UUIDs in a common format like
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
.
If an idempotency key was used, its value is mirrored back into the
Idempotency-Key
response header. If a stored response was replayed, the
response will contain the header and value Idempotency-Replay: true
.