Skip to content

Configuration

Explore how to customize GoPotency to fit your specific needs.

The idempotency.Config struct is used to initialize the manager.

manager, err := idempotency.NewManager(idempotency.Config{
// Storage is the backend storage implementation (required)
Storage: store,
// TTL is the time-to-live for idempotency records. Default: 24h
TTL: 24 * time.Hour,
// LockTimeout is the maximum time a lock can be held. Default: 5m
LockTimeout: 5 * time.Minute,
// KeyStrategy is the strategy for generating keys. Default: HeaderBased
KeyStrategy: key.HeaderBased("Idempotency-Key"),
// RequestHasher computes a hash for validation. Default: BodyHasher
RequestHasher: hash.BodyHasher(),
// AllowedMethods: ["POST", "PUT", "PATCH", "DELETE"] by default
AllowedMethods: []string{"POST", "PUT", "PATCH", "DELETE"},
// RequireKey if true, returns 400 if key is missing. Default: false
RequireKey: true,
// ErrorHandler allows custom error responses.
// See the Error Handling guide for more details.
ErrorHandler: func(err error) (statusCode int, body any) {
return 500, gin.H{"error": err.Error()}
},
// Events (optional)
OnCacheHit: func(key string) {
metrics.Increment("idempotency.hit")
},
OnCacheMiss: func(key string) {
metrics.Increment("idempotency.miss")
},
OnLockConflict: func(key string) {
metrics.Increment("idempotency.lock_conflict")
},
})

Defines how long a response is kept in cache. Once expired, the key can be reused for a new request.

Prevents deadlocks. If a process starts but never finishes (e.g., the server crashes), the lock will expire after this time, allowing retries.

By default, GoPotency only applies idempotency to mutation methods (POST, PUT, PATCH, DELETE). You can customize this list if needed.

If set to true, the middleware will return a 400 Bad Request if the idempotency key is missing for an allowed method/route. This is useful for enforcing idempotency on critical endpoints.

Use hooks to monitor your idempotency layer:

Config{
OnCacheHit: func(key string) {
metrics.Increment("idempotency.hit")
},
OnCacheMiss: func(key string) {
metrics.Increment("idempotency.miss")
},
}