Idempotency
The Idempotency middleware helps build fault-tolerant APIs. Duplicate requestsβsuch as retries after network issuesβwon't trigger the same action twice on the server.
Refer to IETF RFC 7231 Β§4.2.2 for definitions of safe and idempotent HTTP methods.
HTTP Method Categoriesβ
- Safe Methods (do not modify server state):
GET
,HEAD
,OPTIONS
,TRACE
- Idempotent Methods (identical requests have the same effect as a single one): all safe methods plus
PUT
andDELETE
According to the RFC, safe methods never change server state, while idempotent methods may change state but remain safe to repeat.
Signaturesβ
func New(config ...Config) fiber.Handler
func IsFromCache(c fiber.Ctx) bool
func WasPutToCache(c fiber.Ctx) bool
Examplesβ
Import the middleware package:
import (
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/idempotency"
)
Once your Fiber app is initialized, configure the middleware:
Default Config (Skip Safe Methods)β
By default, the Next
function skips middleware for safe methods only:
app.Use(idempotency.New())
Skip Idempotent Methods Insteadβ
Skip all idempotent methods (including PUT
and DELETE
) by overriding Next
:
app.Use(idempotency.New(idempotency.Config{
Next: func(c fiber.Ctx) bool {
// Skip middleware for idempotent methods (safe + PUT, DELETE)
return fiber.IsMethodIdempotent(c.Method())
},
}))
Custom Configβ
app.Use(idempotency.New(idempotency.Config{
Lifetime: 42 * time.Minute,
// ...
}))
Configβ
Property | Type | Description | Default |
---|---|---|---|
Next | func(fiber.Ctx) bool | Function to skip this middleware when it returns true ; use IsMethodSafe or IsMethodIdempotent . | func(c fiber.Ctx) bool { return fiber.IsMethodSafe(c.Method()) } |
Lifetime | time.Duration | Maximum lifetime of an idempotency key. | 30 * time.Minute |
KeyHeader | string | Header name containing the idempotency key. | "X-Idempotency-Key" |
KeyHeaderValidate | func(string) error | Function to validate idempotency header syntax (e.g., UUID). | UUID length check (36 characters) |
KeepResponseHeaders | []string | List of headers to preserve from original response. | nil (keep all headers) |
Lock | Locker | Locks an idempotency key to prevent race conditions. | In-memory locker |
Storage | fiber.Storage | Stores response data by idempotency key. | In-memory storage |
Default Config Valuesβ
var ConfigDefault = Config{
Next: func(c fiber.Ctx) bool {
// Skip middleware for safe methods per RFC 7231 Β§4.2.2
return fiber.IsMethodSafe(c.Method())
},
Lifetime: 30 * time.Minute,
KeyHeader: "X-Idempotency-Key",
KeyHeaderValidate: func(k string) error {
if l, wl := len(k), 36; l != wl { // UUID length is 36 chars
return fmt.Errorf("%w: invalid length: %d != %d", ErrInvalidIdempotencyKey, l, wl)
}
return nil
},
KeepResponseHeaders: nil,
Lock: nil, // Set in configDefault so we don't allocate data here.
Storage: nil, // Set in configDefault so we don't allocate data here.
}