I’m developing a wcf based solution for a webservice layer that “occasionally-connected” mobile devices will be using. The service will not be using queuing (at this stage) due to the additional complexities, and so it will instead be operating a simple Request / Response approach.
Of course, being a mobile device, it is possible that the devices may go out of signal mid insert / update. The webservice itself may have completed the transaction, but the client will never receive this message. Due to this, it will resend the request up, at which point the server needs to recognise this as a duplicate request, and return the same response that it tried on the first instance.
Hence I am trying to make the services Idempotent. In order to achieve this, I am implementing Request Paramter DTO objects, which consist of the RequestID, plus the parameters needed to complete the call.
However, my difficulty is in implementing a way of monitoring the request ids. SInce the service is currently stateless, the only way I can currently envision is to have a ServiceRequest table in the database, which will take the RequestID as a primary. Obviously querying on this will indicate whether the request has already been actioned, as the client will be sending up the same RequestID. But the service also needs to know what message to send back. In the case of an insert/update, the affected aggregate root id will also need to be stored somewhere, whether directly on the request table, or in a RequestToObjectLookup table
So, I’m wondering if there is a best practice way of implementing this? My thoughts are to have a ServiceRequest table(s) (specific to service), that stores requestids, additional info, and also a lookup to the result object id (on a save/insert/update). So when a new request comes in, this table can be consulted first before proceeding with the rest of the request, whether that be to perform the save, or just return the previously updated object (that was actioned on the first request attempt).
I’m also thinking (as stated) that I only need to keep the root aggregate id referenced with the request, as I should just be able to use relationships to attain the rest of the info.