Implementing idempotency in microservices

The DevPrime platform offers automatic Idempotency functionality for use in microservices.

We will implement an example in backend mode where you do not need to pass a key to consume the microservice API. The process automatically manages the Idempotency confrome the payload of the API.

The first step to enabling idempotency is to modify the “Idempotency” setting in Idempotency in “DevPrime_App”. If Deopis has not done so, it is necessary to add a second State to the persistence of the idempotency.

Parameters used in configuration

  • Alias indicates the State used in the persistence of Idempotency
  • Duration is used to set the time of the command’s duplicate control record.
  • Flow indicates Idempotency type and can be set to “backend” or “frontend”
  • Key is used to set a required key in the head in flow “frontend”
  • Scope limits the performance of the information and uses the “all|web|stream” parameters
  • Action defines whether the idepontencia will be automatic or manual with the parameters “auto|manual”

Creating a microservice to use in the example

We will use a microservice based on the DevPrime platform

Starting Idempotency setup

Setting the idempotency in the “DevPrime_App” key
Change idempotency setting in “Enabled” to “true”
code .\src\app\appsettings.json

1
2
3
4
5
6
7
8
9
    "Idempotency": {
      "Enable": "true",
      "Alias": "State2",
      "Duration": "86400",
      "Flow": "backend",
      "key": "idempotency-key",
      "Scope": "all",
      "Action": "auto"
    }

Include a second persistence in the “DevPrime_State” key
In this example we will use a local Redis with a default password
code .\src\app\appsettings.json

1
2
3
4
5
6
7
8
9
{
  "enable": "true",
  "alias": "State2",
  "dbtype": "redis",
  "connection": "127.0.0.1:6379,password=LltF8Nx*yo",
  "timeout": "5",
  "retry": "2",
  "durationofbreak": "45"
}

Initiating automatic Idempotency in the microservice

Now it’s time to test the configuration. Before starting the microservice make sure that you have activated the containers and created the queue in RabbitMQ.

Run the app and post the Order API
In the example below we are using a standard json for the post.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "customerName": "Bill",
  "customerTaxID": "string",
  "itens": [
    {
      "description": "short",
      "amount": 1,
      "sku": "XNY1AC",
      "price": 100
    }
  ],
  "total": 100
}

Note in the Log the information of the idempotência
The Idempotency process has automatically entered to protect this HTTP request without the need for any consumer-side API information.
DevPrime Capabilities idempotency

Make a second one identical post by the Order API
By observing this second scenario it is already possible to realize that the Idempotency protected the microservice preventing a duplicate inclusion.

The API has already received a return rejecting the duplicate POST
DevPrime Capabilities idempotency

By analyzing the Log we were able to follow the whole process of the idempotência
DevPrime Capabilities idempotency

Starting manual Idempotency in the microservice

DevPrime allows you to manually enter a specific method that will support idempotência. The first step is to change the main configuration and then go directly into the method to add the configuration.

** Changing the “Action” key to “Manual”**

1
2
3
4
5
6
7
8
9
    "Idempotency": {
      "Enable": "true",
      "Alias": "State2",
      "Duration": "86400",
      "Flow": "backend",
      "key": "idempotency-key",
      "Scope": "all",
      "Action": "manual"
    }

Using the “Action” option as “manual” if you run the microservice again and make a duplicate post you will notice that it will not reject because the automatic process is off.

** Activating idempotency in a method**
As the process is now manual we will activate Idempotency in each method to be protected. In the example below we demonstrate this possibility directly in the Web Adapter.
code src\Adapters\Web\Order.cs

Find the “Order” API on the Web Adapter and make the modification as shown.

1
2
3
4
5
app.MapPost("/v1/order", async (HttpContext http, IOrderService Service, DevPrime.Web.ViewModels.Order.Order command) => await Dp(http).Pipeline(() =>
        {
            Dp(http).Idempotency.Enable = true;
            Service.Add(command.ToApplication());
        }));

Run again and you’ll notice that the Idempotency feature is back up and running, but only for the POST in the “/v1/order” API.

Implementing idempotency in microservices
Idempotency in microservices and REST APIs

Last modified March 13, 2022 (4cc8d5e)