Implementing idempotency in microsservices

The Devprime platform offers automatic idempotency functionality for use in microservices.

We’ll implement an example in backend mode where you don’t need to pass a key to consume the microservice API. The process automatically manages the idempotency and the API payload.

The first step to enabling idempotency is to modify the “Idempotency” setting in Idempotency in the “Devprime_App”. Later, if you haven’t done so, you need to add a second state for 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 duplicate control register.
  • Flow indicates type of Idempotency and can be set to “backend” or “frontend”
  • Key is used to set a key required in the head in the Flow frontend
  • Scope limits the performance of ideopontence and uses the “all|web|stream” parameters
  • Action defines whether ideopontence will be automatic or manual with the “auto|manual” parameters

Creating a microservice to use in the example

We will use a microservice based on the Devprime platform

Starting the idempotency configuration

Setting the idempotency in the “Devprime_App” key
Change the Idempotency setting to “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"
}

Starting automatic idempotency in the microservice

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

Run the application and make a post via 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
}

Observe in the Log the information of the idempotency
The idempotency process automatically came in to secure this HTTP request without the need for any information from the API consumer side.
Devprime Capabilities idempotency

Make a second identical post via the Order API
By observing this second scenario, it is already possible to see that idempotency protected the microservice by preventing a duplicate inclusion.

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

By analyzing the Log, we can follow the entire idempotency process
Devprime Capabilities idempotency

Initiating manual idempotency in the microservice

Devprime allows you to manually enter a specific method that will support idempotency. The first step is to change the main setting and then go directly to the method to add the setting.

** 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"
    }

When 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 turned off.

** Enabling idempotency in a method **
Since the process is now manual, we will enable idempotency on each method to be protected. In the example below we demonstrate this possibility directly in the Web Adapter.
code src\Adapters\Web\Order.cs

Locate the “Order” API in 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 it again and you will notice that the idempotency feature is back to work, but only for POST in the “/v1/order” API.

Implementing idempotency in microsservices
Idempotency in microsservices and REST APIs

Last modified August 20, 2024 (2f9802da)