Incorporating idempotency is an important part of building robust and predictable APIs. In basic terms, idempotence is a scenario where how many times the action may be performed but the outcome remains the same.
for a basic example, take f(x) = x*x, How many times you may call f(5) it’s always going to be the same outcome 25, This request is idempotant.
Photo by Jordan Harrison on Unsplash
Idempotence in HTTP
When talking about idempotence in the context of HTTP another term that pops up is safety, safety is where the request doesn’t mutate data on invocation. The table below shows commonly used HTTP methods and there safety and idempotency.
+——————-+————–+——————-+
| Http Method | Saftey | Idempotency |
+——————-+————–+——————-+
| GET | Yes | Yes |
| PUT | No | Yes |
| POST | No | No |
| DELETE | No | Yes |
| PATCH | No | No |
+——————-+————–+——————-+
Some methods are idempotent by the get-go. Take GET for an example, how many time you may call the GET method it results with the same outcome.
ℹ To be Idempotent only the action/intention is considered, the HTTP resdponse status code may differ, ie — The initial DELETE call may return 200, but the successive ones may return 404.
Why is Idempotency important for building reliable APIs?
Think of such a scenario; Networks are sometimes unreliable, In cases where an API consumer may send and request but because of a technical difficulty not receive the response. This may not be a problem for a GET request where it can be retried but is an issue for non-idempotent HTTP methods such as POST.
Introducing the idempotency key
With the prior given example let’s tackle the idempotency problem. To solve this problem we need an identifier to help denote whether the request is idempotent which can be facilitated by an idempotency key.
With an idempotency key, the server can know if the request is idempotent or not by keeping track of the keys sent by the client and treating a request idempotent if it comes with a previously used key.
Example Payment Scenario with Idempotency
Given above is an example usage of a payment scenario where idempotency is used and is incorporated into the business logic.
Recommendations for implementing idempotency in APIs
No defacto standard is offered and different implementers follow their own standards but the following points are kept constant.
- Use an HTTP header such as x-idempotency-key
- Invalidate idempotency keys after a pre-defined time period, therefore after the time period passes the request is treated as a new non-idempotent request.
- Validate bad behaving idempotency keys, In cases where the client may send a different payload for a certain key in the subsequent retries that may be treated as a new request or a bad request.
API Consumer Considerations
A client application that is using an API implementing idempotency can follow the guidelines below to ensure proper usage.
- Idempotency key can be any value, most recommend is the use of a UUID.
- Sending idempotent requests for polling status of objects should be avoided, as some APIs may allow that.
- When a request is unsuccessful better to follow a retry policy such as exponential backoff. This will ensure that in a scenario where the Server is amidst an incident that it’s not flooded with requests.
**Resources Used
**https://developer.mozilla.org/en-US/docs/Glossary/Idempotent
https://stripe.com/en-US/blog/idempotency