Idempotence is the property of certain operations in mathematics and computer science, that can be applied multiple times without changing the result beyond the initial application.
When you click the “Place Order” button on magical unicorn e-commerce site, you expect your order to be submitted only once. You also expect that your credit card on on the order you just placed shouldn’t happen more than once.
There are different ways to handle idempotency at various levels of your application.
Persistence
Context is important. In my context, I’m using a ACID compliant database (MySQL) for storing my current state.
I’m also using Entity Framework as my ORM for handling data/entity state changes.
I can handle idempotency right before I perform my database operation to modifying application state within a database transaction.
Message Identification
In a previous post, Identify Commands & Events, I described creating a Envelope<T> which contains a MessageId that we can use to keep track of messages that have been processed.
View the code on Gist.
In my example, I’m using NancyFX, which uses Modules instead of Controllers. Even if you are unfamiliar with Nancy, you should be able to understand the gist.
In our route we are going to add a new parameter {MessageId:Guid} which we will then use when creating our Envelope.
View the code on Gist.
Handling
When we make our changes to our database model/entity, we will also attempt to add a new Idempotent object to its mapped table. First lets create an entity that will contain our unique Id.
View the code on Gist.
With our first pass, lets add a new Idempotent to the database context and check if there is a duplicate key exception. I’m using MySQL and checking for Error Number 1062 that represents a unique key error.
View the code on Gist.
SaveChangeAsync
The above code is a one way of how handle idempotent commands, however once you implement this more than once you will realize that the next step is to add another method to your Entity Framework Context that will handle the saving of the idempotent entity.
View the code on Gist.
How do you?
How do you handle idempotent commands? I’d love to hear about other implementations or uses. Comment below or on twitter.
Other Posts
- Identify Commands & Events
- Thin Controllers with CQRS and MediatR
- Query Objects instead of Repositories
- Mediator Pattern using MediatR and Unity
- Query Objects with a Mediator
The post Idempotent Commands appeared first on CodeOpinion.