Idempotency in REST
Idempotency in RESTful APIs means that making multiple identical requests results in the same effect as making a single request. In other words, no matter how many times you send the same request, the server's state will not change after the first successful request. This concept is essential to ensure reliability and consistency, particularly in cases where clients might retry requests due to network timeouts or failures.
HTTP methods such as GET, PUT, DELETE, HEAD, OPTIONS, and
TRACE are idempotent because repeating these requests will not alter the
outcome beyond the first application. For example, sending multiple DELETE
requests for the same resource will result in the resource being deleted after
the first request, with no further effect from subsequent requests. On the
other hand, POST and PATCH are generally not idempotent because repeating them
can create multiple resources or cause incremental changes.
To implement idempotency in non-idempotent operations like
POST, APIs often use idempotency keys — unique identifiers sent with each
request. These keys help servers detect repeated requests and return the same
response without performing the operation multiple times. Idempotency improves
error handling, fault tolerance, data integrity, and caching capabilities in
distributed systems.
Thus, idempotency is a key design principle for RESTful APIs
ensuring that clients can safely repeat requests without unintended side
effects, making the system more robust and predictable.[1][2][3][4]
Here is an example of how to implement an idempotent POST
method in C# for a RESTful API using ASP.NET Core.
The key idea is to use an idempotency key sent in the request header to ensure
that repeated requests with the same key do not create duplicate resources.
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
private static readonly
Dictionary<string, Order> _orders = new();
private static readonly object _lock
= new();
[HttpPost]
public IActionResult
CreateOrder([FromBody] Order order, [FromHeader(Name =
"Idempotency-Key")] string idempotencyKey)
{
if
(string.IsNullOrEmpty(idempotencyKey))
{
return
BadRequest("Idempotency-Key header is required.");
}
lock (_lock)
{
if
(_orders.ContainsKey(idempotencyKey))
{
// Return the existing
order for this idempotency key
return
Ok(_orders[idempotencyKey]);
}
// Process to create the
order
order.Id =
Guid.NewGuid().ToString();
_orders[idempotencyKey] =
order;
// Return created response
return
CreatedAtAction(nameof(GetOrder), new { id = order.Id }, order);
}
}
[HttpGet("{id}")]
public IActionResult GetOrder(string
id)
{
var order =
_orders.Values.FirstOrDefault(o => o.Id == id);
if (order == null)
{
return NotFound();
}
return Ok(order);
}
}
public class Order
{
public string Id { get; set; }
public string Product { get; set; }
public int Quantity { get; set; }
}
Explanation:
·
The
client sends a POST request to create an order and includes a unique Idempotency-Key header.
·
The
server checks if the key has been seen before. If yes, it returns the earlier
created order, preventing duplicates.
·
If not,
the order is created, stored against the key, and returned.
·
The lock
ensures thread safety in this simple in-memory example, which you would replace
with a database in real applications.
This approach prevents creating multiple orders if the client retries the same request due to network issues or timeouts, thus making the POST operation idempotent in practice.[1][2]
⁂
![]()
1.
https://developer.mastercard.com/mastercard-processing-digital/documentation/api-basics-section/idempotency/
2.
https://restfulapi.net/idempotent-rest-apis/
3.
https://www.geeksforgeeks.org/javascript/what-is-an-idempotent-rest-api/
4.
https://keploy.io/docs/concepts/reference/glossary/idempotency/
5.
https://developer.mozilla.org/en-US/docs/Glossary/Idempotent
6.
https://www.milanjovanovic.tech/blog/implementing-idempotent-rest-apis-in-aspnetcore
7.
https://cardsapidocs.thredd.com/docs/what-is-idempotency
8.
https://blog.dreamfactory.com/what-is-idempotency
9.
https://zuplo.com/learning-center/implementing-idempotency-keys-in-rest-apis-a-complete-guide
2. https://keploy.io/docs/concepts/reference/glossary/idempotency/
Comments
Post a Comment