-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Closed
Labels
Description
Feature Description
Idempotency is a guarantee that enables the client to have safe retries if no response (or a 500 response) is received from the server, by using an "idempotency key" that is supplied by client to denote the initial request and its retry requests as a singular set of intention (instead of multiple intentions).
Production examples of idempotency:
Additional Context (optional)
When the middleware received a request...
- ...without an idempotency key
- It will just call the
Next()handler and that's all.
- It will just call the
- ...with an idempotency key, but such key does not exist/already expired
- Lock the idempotency mutex lock with idempotency key as the key. The lock is typically a distributed redis lock. We should just provide an interface for outer libraries/users to implement.
- After acquired lock, check the existence of idempotency key again in storage.
- The middleware will call
Next()handler, and- If returned non-nil error, return the error and skip idempotency saving.
- Save the response status, body, and all headers specified in
PersistResponseHeaders - Unlock the idempotency mutex lock with idempotency key as the key.
- Lock the idempotency mutex lock with idempotency key as the key. The lock is typically a distributed redis lock. We should just provide an interface for outer libraries/users to implement.
- ...with an idempotency key, and such key exists/not expired
- Return the saved response (status, body, and all headers saved) for such key.
Code Snippet (optional)
package main
import (
"log"
"time"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/idempotency"
)
func main() {
app := fiber.New()
app.Use(idempotency.New(idempotency.Config{
// LifeTime is the backtrack time window of the presence of an idempotency key. Default is 24h.
LifeTime: time.Hour * 24,
// KeyHeader is the header for looking up the idempotency key from. Default is "X-Idempotency-Key".
KeyHeader: "X-Idempotency-Key",
// Storage is the storage of idempotency responses. Default is a in-memory fiber.Storage.
Storage: fiberstore.NewRedis(), // this is to just illustrate a storage that implements fiber.Storage
// PersistResponseHeaders is a set of headers to persist. Default is nil.
PersistResponseHeaders: []string{
fiber.HeaderContentType,
fiber.HeaderContentLength,
fiber.HeaderSetCookie,
},
}))
app.Post("/hello", func(ctx *fiber.Ctx) error {
return ctx.SendString(time.Now().String())
})
log.Fatal(app.Listen(":3000"))
}Checklist:
- I agree to follow Fiber's Code of Conduct.
- I have checked for existing issues that describe my suggestion prior to opening this one.
- I understand that improperly formatted feature requests may be closed without explanation.
Reactions are currently unavailable