Show TOC

Background documentationImplementing Idempotent Web Services Locate this document in the navigation structure

 

You should implement as idempotent any synchronous service for which the following applies:

  • The service changes the persistent business data in an application system.

  • A repeated successful execution of exactly the same request would create duplicate business data or risk process inconsistencies.

For more information, see Idempotent Web Services.

Prerequisites

  • Service consumers connecting to idempotent Web services must use the MessageHeader element and its subelement UUID in the services’ request messages.

    The UUID values must be globally recognizable and satisfy the format that is specified in IETF's RFC 4122. If you do not use the element when you call the services, the services do not behave in an idempotent manner. You can generate UUID in one of the following ways:

    • When developing consumers in Java, use the java.util.UUID class.

    • When developing consumers in ABAP, use function module GUID_CREATE followed by the method call CL_GDT_CONVERSION=>GUID_OUTBOUND. Note that the GUIDs used internally in ABAP systems do not satisfy the UUID format.

    For more information, see http://www.ietf.org/rfc/rfc4122.txt.

  • Before calling the idempotent services, the underlying framework has to be configured, including the time frame for which the system keeps responses for already processed service calls.

    For more information, see SAP Note 1097348.

Procedure

Designing Service Interfaces
  • Make sure the service operation's input and output message data type contain a MessageHeader element typed with GDT BasicBusinessDocumentMessageHeader - or one of its predefined projections that contain the UUID element - as the first child element of the root element.

  • The MessageHeader element can be declared as optional (occurrence 0..1).

  • If your service operation's namespace contains a version of the full-fledged BusinessDocumentMessageHeader (or a projection thereof) that contains the UUID element, and if you want to offer synchronous and asynchronous services with the same signature, you can also use the this GDT.

Implementing Idempotent Services
  1. Extract the Business Document Message UUID from the Business Document Message Header. Service consumers have to explicitly “request” idempotent behavior by providing a non-empty value for the message UUID.

  2. Create an instance of the NW helper class for “idempotent Web services” using its factory class. This can fail if the idempotency framework has not been configured yet, in which case the system throws a cx_soap_idp_fault exception.

  3. Call the helper class' method to check if the incoming request has already been processed.

    The helper class creates an enqueue for the request message UUID at this point already. This ensures that two consumers cannot share the same request message UUID, or that two fast consecutive calls by the same consumer are detected. Creating the enqueue can fail for two reasons:

    • System failure, for example, enqueue server cannot be reached.

      This is an unexpected abnormal condition and shall be treated as an exception.

    • The same request has already been received, but has not been fully processed yet.

      A stored response thus is not available. This shall not lead to an exception, but a second attempt to call the helper class's method shall be made. Only if the second attempt fails as well should an exception be thrown.

  4. If the result is “yes”, retrieve the stored response, and directly return the response to the consumer. Do not process the request any further, skip the next steps until the last step.

    Since the response may already have been deleted, retrieving it may fail. Do not process the request, trying to produce a new response, in that case, but throw an exception.

  5. Process the request according to the usual implementation guidelines, that is, SET UPDATE TASK local, call inbound mapping, preprocessing BAdI, BAPI, post-processing BAdI, outbound mapping.

    Make sure you do not call CL_SOAP_COMMIT_ROLLBACK=>COMMIT() yet.

  6. If both the following conditions are met, store the response “message” (using the ABAP proxy structure) using the NW helper class's method:

    • No application errors (reported as messages in the output message's Log element) occurred.

    • Idempotency is requested by the consumer.

  7. If still no errors occurred, call method CL_SOAP_COMMIT_ROLLBACK=>COMMIT(). Else, call method CL_SOAP_COMMIT_ROLLBACK=>ROLLBACK().

  8. Take care of exception handling.

  9. End method.