Add contract-declared HTTP idempotency - #244
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Original request
Declare HTTP idempotency in the endpoint contract so a typed client can retry a request without executing the server mutation twice. Keep ordinary client calls unchanged and deliver the library changes against
development.What changed
.idempotent()to mutation contracts. The client automatically creates one request key and preserves it, along with the serialized body, across configured HTTP retries. Separate client invocations get separate keys.Reasoning
The contract identifies mutations safe for transport retries. Consumers keep normal endpoint calls and their shared retry middleware; the server owns response replay. Applications retain their resource authorization and verified user/tenant scope.
The existing low-level middleware remains available. Replay is bounded and process-local, using the existing 24-hour / 1,000-entry / 65,536-byte defaults per endpoint. Reusing a key asserts identical input. Restarts, expiry, separate replicas and thrown failures are outside a durable exactly-once guarantee. CORS remains an explicit application policy.
This change does not add form/session attempt tracking or manual retry APIs.
Blog post
Not applicable: this is a library API change. The client/server READMEs, documentation site and changeset describe the supported behavior.
Screenshots / preview evidence
Screenshots are not applicable to the HTTP transport behavior. No hosted PR preview is configured. Automated tests cover same-key concurrency, authorization, scope isolation, response capture, explicit batching, automatic retries and fresh keys for separate calls.
Validation
npm run lintnpm run buildnpm run test: 265 files, 5,115 tests; no type errors.npm run typecheck:schema-siteandnpm run typecheck:docs-sitenpm run test:packages: 22 packages, 52 entry points; declarations, licenses and browser bundle passed.637356f2: Node 24 lint/build/tests/coverage, dependency audit, packed packages, website builds/API references, PostgreSQL integration, S3 storage integration and demo API/browser/telemetry E2E.