idempotency

package module
v0.0.0-...-e8f45fd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 31, 2026 License: MIT Imports: 7 Imported by: 0

README

go-idempotency

HTTP middleware for idempotent request handling in Go. Prevents duplicate processing of requests by caching responses based on idempotency keys—essential for payment, financial, and other critical APIs.

Features

  • 🔒 Prevents duplicate operations using idempotency keys
  • 🚀 Multiple storage backends: in-memory and Redis
  • Concurrent request handling with distributed locking
  • 🎯 Request fingerprinting (method + path + body hash)
  • ⏱️ Configurable TTL for cached responses
  • 🧪 Thoroughly tested with 90%+ coverage
  • 📦 Zero dependencies (except storage drivers)

Installation

go get github.com/AnandSundar/go-idempotency

Documentation

Overview

Package idempotency provides HTTP middleware for idempotent request handling. It prevents duplicate processing of requests by caching responses based on idempotency keys, commonly used in payment and financial APIs.

Index

Constants

View Source
const (
	// DefaultHeaderName is the default HTTP header for idempotency keys
	DefaultHeaderName = "Idempotency-Key"
	// DefaultTTL is the default time-to-live for cached responses
	DefaultTTL = 24 * time.Hour
)

Variables

View Source
var (
	// ErrRequestInProgress is returned when a request with the same key is already being processed
	ErrRequestInProgress = errors.New("request with this idempotency key is already in progress")

	// ErrNotFound is returned when a cached response is not found
	ErrNotFound = errors.New("cached response not found")

	// ErrLockFailed is returned when acquiring a lock fails
	ErrLockFailed = errors.New("failed to acquire lock")
)

Functions

func Middleware

func Middleware(store Store, opts ...Option) func(http.Handler) http.Handler

Middleware returns an HTTP middleware that enforces idempotency. It checks for an idempotency key in the request header, and if found, either returns a cached response or processes and caches the new response.

Types

type CachedResponse

type CachedResponse struct {
	StatusCode int         `json:"status_code"`
	Headers    http.Header `json:"headers"`
	Body       []byte      `json:"body"`
	Timestamp  time.Time   `json:"timestamp"`
}

CachedResponse represents a cached HTTP response

type Config

type Config struct {
	HeaderName string
	TTL        time.Duration
	KeyFunc    KeyFunc
}

Config holds middleware configuration

type KeyFunc

type KeyFunc func(r *http.Request, idempotencyKey string) (string, error)

KeyFunc generates a unique key from the request and idempotency key

type Option

type Option func(*Config)

Option is a functional option for configuring the middleware

func WithHeaderName

func WithHeaderName(name string) Option

WithHeaderName sets the HTTP header name for idempotency keys

func WithKeyFunc

func WithKeyFunc(fn KeyFunc) Option

WithKeyFunc sets a custom key generation function

func WithTTL

func WithTTL(ttl time.Duration) Option

WithTTL sets the time-to-live for cached responses

type Store

type Store interface {
	// Get retrieves a cached response by key
	Get(key string) (*CachedResponse, error)

	// Set stores a response with the given key and TTL
	Set(key string, response *CachedResponse, ttl time.Duration) error

	// Lock acquires a lock for the given key to prevent concurrent processing
	// Returns an unlock function that must be called to release the lock
	Lock(key string) (unlock func(), err error)
}

Store defines the interface for storing and retrieving cached responses

Directories

Path Synopsis
examples
server command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL