Idempotency
In this guide, you'll learn how to make operations idempotent.
DBOS allows users to send any request with an idempotency key to guarantee it only executes once, even if the request is sent multiple times. This is especially useful if your operations have side effects like making a payment or sending an email.
Setting Idempotency Keys
DBOS idempotency keys are UUIDs. Idempotency keys are required to be globally unique for your application. There are many popular libraries for generating UUIDs in TypeScript, such as uuid.js.
To make a request idempotent, generate a UUID and set the request's dbos-idempotency-key
header field to that UUID.
No matter how many times you send that request, as long as each request has the idempotency key set, the operation will only execute once (if the request is for a step, it may be retried multiple times, but will not re-execute after successfully completing).
It's not a coincidence that both idempotency keys and workflow identities are UUIDs. If you run a workflow with an idempotency key UUID, the identity of that execution is set to that UUID.
Manually Setting Idempotency Keys
Idempotency keys are not automatically used for handlers.
Instead, if you invoke an operation from a handler, you can manually pass in an idempotency key as an argument to context.invoke
.
The syntax for invoking Class.operation
with an idempotency key is:
@GetApi(...)
static async exampleHandler(ctxt: HandlerContext, ...) {
const idempotencyKey = ...;
await ctxt.invoke(Class, idempotencyKey).operation(...);
}
Idempotency Example
Let's look at this workflow endpoint:
@GetApi('/greeting/:user')
@Workflow()
static async helloWorkflow(ctxt: WorkflowContext, @ArgSource(ArgSources.URL) user: string) {
return await ctxt.invoke(Hello).helloTransaction(user);
}
Each request to this endpoint has the side effect of incrementing a database counter. However, if we set the idempotency key, we can resend a request multiple times without side effects:
If we curl
this endpoint normally multiple times, each request increments the counter:
curl http://localhost:3000/greeting/dbos
However, if we set the idempotency key in the header and resend the request many times, each request returns the same response and the workflow only executes once:
curl -H "dbos-idempotency-key: 123e4567-e89b-12d3-a456-426614174000" http://localhost:3000/greeting/dbos