Monday, October 01, 2012

SOA design pattern: Idempotent Capability

In the newly released "SOA with REST" book by Thomas Erl et al. (http://servicetechbooks.com/rest) , a few new design patterns are presented for SOA. One of these is "Idempotent Capability" on page 470. In principle, idempotency is important for both SOAP and RESTful services, but with REST, idempotency and safety of requests must be dealt with on a HTTP level: it's in the specs. For example, HTTP "PUT" must be idempotent, so if you implement it, you must take care of this. SOAP does not have idempotency requirements built into the specs. So maybe this is the reason why this pattern did not show up before.

I have written on idempotency before in this blog ( http://ignazw.blogspot.be/2012/01/idempotent-services.html ), and I am surprised that the described pattern does not correctly deal with service requests that will create or update data. It reads: "The design of an idempotent capability can include the use of a unique identifier with each request so that repeated requests (with the same identifier value) that have already been processed will be discarded or ignored by the service capability, rather than being processed again."

This statement bypasses a fundamental characteristic of idempotency, namely that the response to the same request must always be the same. Hence, the service capability should not discard or ignore the duplicate request at all! Rather, it should make sure the identical response to the previous identical request is given. This is not a simple task, but essential for service clients that contain state that is dependent on the service capability's outcome, for example for stateful business processes using the service.

Imagine this, not so uncommon scenario: The client issues an update request. However, the response does not arrive within the predefined time out. The request is sent a second time. (load balancers and reverse proxies can do this, too; seemingly hidden from the end user.) What response should I get? A correct idempotency implementation should respond with the same response that never got to me the first time. If I would receive nothing, or, let's say, a duplicate key exception, then my business may be in an erroneous state: I may have created a resource, but I miss the reference to it!

Ergo: idempotent service capabilities should not discard or ignore a duplicate request!

No comments:

Post a Comment