Change log:
Date: | Author: | Version: | Changes: |
---|---|---|---|
23 October 2023 | Emil Ion Ifrim | 1.0 | Doc. created |
Introduction
The purpose of this section is to describe how to configure idempotency of REST endpoints.
Overview
Idempotency means that sending the same request multiple times will produce the same result, without changing the state of the server or the resource.
Idempotency is important for REST APIs in general, but especially for event-driven architecture, where multiple components may communicate with each other through messages that trigger REST API calls. If a message is lost, duplicated, or delayed, it may cause inconsistent or unexpected outcomes, such as data corruption, duplication, or loss. By ensuring that your REST APIs is idempotent , one can reduce the risk of these errors and improve the reliability and resilience of the system.
GET, HEAD, OPTIONS, PUT and DELETE are idempotent methods. POST is not idempotent.
One of the best practices for designing idempotent and safe REST APIs is to use the appropriate HTTP methods for regular operations.,
Prerequisites
This feature is available from Rator Core version 12 and up
Enablement
By default, idempotency of the POST requests is disabled, as it adds some overhead by persisting each POST response. To enable it, the following parameter needs to be set in Properties configuration file:
rest.api.idempotency.enabled=true
Also, to uniquely identify each idempotent request, the Idempotency-key header parameter needs to be sent in the request.
The value of this parameter should be a unique random string, recommended in a form of UUID v4.
Here is an example (curl command, only header parameter):
--header 'Idempotency-Key: 734b7147-e367-46fd-bc5c-85b7a95dcebf'
Note: this header should only be sent for POST requests, otherwise it will be ignored.
Error handling
When concurrent requests (with the same Idempotency-key) happen, a specific error will be returned :
< HTTP/1.1 500 < X-Content-Type-Options: nosniff < X-XSS-Protection: 1; mode=block < Cache-Control: no-cache, no-store, max-age=0, must-revalidate < Pragma: no-cache < Expires: 0 < X-Frame-Options: DENY < Vary: Origin < Vary: Access-Control-Request-Method < Vary: Access-Control-Request-Headers < Content-Type: application/json;charset=UTF-8 < Content-Length: 223 < Date: Mon, 23 Oct 2023 11:11:19 GMT < Connection: close < { "errorCode":500, "consumerMessage":"An exception occurred while processing the request.", "applicationMessage":"Request already in progress OR in inconsistent state (generate a new Idepotency-key)!", "stacktraceElement":null} }
Note: This can also happen when the first request failed with a system error.
Solution; Generate a new Idempotency-key and resend the request.
Retention and Cleanup
A database job is responsible for removal of old/historical IDEMPOTENT_ACTION records.
The recommendation is to keep this table as small as possible, for performance considerations.