danschultzer
Just released IdempotencyPlug, a plug based library that makes POST and PATCH requests idempotent using an Idempotency-Key HTTP header. It follows the IETF Idempotency-Key HTTP Header Field specification draft.
The details
I wrote a blog post on the process and motivations: https://danschultzer.com/posts/idempotencyplug-idempotent-post-requests
Some TLDR excerpts:
An idempotent request ensures that a request only affects the resource at most once. In REST all methods are idempotent except POST and PATCH.
Take the endpoint
POST /api/paymentsthat initiate a new payment charge at a payment processor. If the client experiences a network interruption during the request, how can the client safely retry the request without creating a new charge?
These are the requirements for idempotent request handling:
- Require a single
Idempotency-KeyHTTP header for all POST and PATCH requestsIdempotency-Keyvalue MUST be unique for a URIIdempotency-Keyvalue MUST NOT be reused with a different request payload- First-time requests MUST be processed normally, and the response cached
- Duplicate requests MUST return the cached response
- Concurrent requests MUST return an error
- We MUST handle unexpected process termination
- The cached responses SHOULD expire after 24 hours
- The cache SHOULD be distributed and persisted
Links
Github: https://github.com/danschultzer/idempotency_plug
Hex: https://hex.pm/packages/idempotency_plug
Docs: https://hexdocs.pm/idempotency_plug/README.html
I hope you find it useful, and as always, any contributions are much appreciated! ![]()
Trending in Announcing
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #ai
- #phoenix_html
- #elixirconf-us
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 6- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
danschultzer
Released
v0.2.0last week that makes customization simpler with MFA configuration values instead of behaviors: idempotency_plug/CHANGELOG.md at main ¡ danschultzer/idempotency_plug ¡ GitHubD4no0
Iâve always wondered, when does this actually happen, if there is a network interruption, then the request will fail anyway from both sides, no? or is this a guarantee in systems where repeating same requests multiple times is a thing?
LostKobrakai
You cannot know if the other side was even reached or reached without our knowledge.
danschultzer
Yup what @LostKobrakai said. Stripe has a great blog post about it: Designing robust and predictable APIs with idempotency
D4no0
Okay, then if we were to treat the request as a single transaction that gets committed only if the client receives the response, then we wouldnât need this? because at the end of the day we work over TCP and the protocol guarantees delivery.
danschultzer
Depending what you mean with receive response, you will need an acknowledgement that the response was received, and then what if you donât get that and it times out? Gets to the Two Generals Problem. At some point the server must commit, and since that happens server-side you will always have a potential state where the commit occurred, but the client donât have the acknowledgement that it happened.
In these cases youâll want to retry the request. Works with idempotent requests like GET, DELETE, and PUT. But if you are dealing with a request thatâs not idempotent like POST then you need some way to ensure the retry doesnât create a new resource, but returns the resource that was created the first time.