danschultzer

danschultzer

Pow Core Team

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/payments that 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-Key HTTP header for all POST and PATCH requests
  • Idempotency-Key value MUST be unique for a URI
  • Idempotency-Key value 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! :smiley:

Showing Posts 1 to 6

danschultzer

danschultzer OP

Pow Core Team

Released v0.2.0 last week that makes customization simpler with MFA configuration values instead of behaviors: idempotency_plug/CHANGELOG.md at main · danschultzer/idempotency_plug · GitHub

D4no0

D4no0

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

LostKobrakai

You cannot know if the other side was even reached or reached without our knowledge.

danschultzer

danschultzer OP

Pow Core Team

Yup what @LostKobrakai said. Stripe has a great blog post about it: Designing robust and predictable APIs with idempotency

D4no0

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

danschultzer OP

Pow Core Team

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.

— All posts loaded —

Where Next? Top

Trending in Announcing Top

woylie
Flop is an Elixir library that applies filtering, ordering and pagination parameters to your Ecto queries. offset-based pagination with...
New
MRdotB
I needed to reuse React components from my Chrome extension in my Phoenix/LiveView backend. I noticed that for Svelte/Vue, there are live...
New
woylie
I released Doggo, a collection of unstyled Phoenix components. https://github.com/woylie/doggo Features Unstyled Phoenix components....
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
anuaralfetahe
Hello Published a new library - ProcessHub! ProcessHub is a library designed to manage process distribution within the Elixir cluster. ...
New
rodloboz
I’ve started working on a new library to run SQL queries and do basic business intelligence. Think “Blazer for Elixir.” Currently it fe...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
AstonJ
This showed up on my feed.. anyone heard of it? Just hype? Ox Alpha is a reasoning model designed for coding, sustained ag...
New
bartblast
Hey folks, I just published a post about Hologram’s funding and where the project goes next - the short version: Curiosum as Main Spons...
New
akoutmos
@hugobarauna, Dr. Dimitrios Koutmos (my brother) and I (Alex Koutmos) have been hard at work on writing a book on how you can use Elixir ...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews