2 KiB
2 KiB
ADR 001: Idempotency for Critical Write Operations
Status
Accepted
Context
Repeated requests (retries/double clicks) can currently create duplicate offers/acceptances. This is problematic because:
- Users may accidentally double-click buttons
- Network issues might cause requests to timeout and be retried
- The system should behave deterministically when handling retries
Decision
We implement idempotency key handling for critical POST endpoints:
- Add
x-idempotency-keyheader support to POST endpoints - Store request results in a database table for replaying responses
- Return cached responses for identical keys
- Apply this to the most critical endpoints:
/offers/:requestId/offers/negotiation/:offerId/offers/accept/:offerId/help-requests
Consequences
Positive
- Eliminates duplicate offers/acceptances from retries
- Makes critical endpoints behave deterministically on retries
- Improves user experience by preventing accidental duplicates
- Follows REST best practices for idempotent operations
Negative
- Adds complexity to request handling
- Requires database storage for idempotency keys
- Slight performance overhead for idempotent requests
Implementation Details
Database Schema
Added idempotency_keys table with:
key: Unique identifier for the request (VARCHAR)response_body: Cached response data (TEXT)created_at: Timestamp of when the key was first used
Middleware
Created requireIdempotencyKey middleware that:
- Checks for
x-idempotency-keyheader in POST requests - If key exists, checks if it has been used before
- If used before, returns cached response
- If new, stores the request and caches the eventual response
Endpoints
Applied to critical write operations:
- POST
/offers/:requestId - POST
/offers/negotiation/:offerId - POST
/offers/accept/:offerId - POST
/help-requests
Testing
Added tests for idempotency behavior in the existing test suite.