Add fixed-window rate limit middleware - #11576
Conversation
|
Thanks for the PR, MVH! I pushed a follow-up that narrows this to the minimum safe fixed-window API and addresses the issues found while comparing it with Hono's middleware:
The package is also wired into the Remix umbrella export as |
|
Thanks for the hardening pass, Michael. I read through the follow-up and the narrower API is better than what I had. The client-identity change is the one I'd have gotten wrong: a Fetch Request has no trusted remote address, and inferring identity from auth/cookie/UA/origin headers is either a bucket-rotation hole or makes unrelated clients share a bucket, so requiring it explicitly is the right boundary. Passing { name, key, window } into a single atomic store op also removes the read-then-write race my version had and the collisions when a global and a route-scoped policy share a store. Dropping the strategy abstraction and shared context for one fixed-window limiter is the right scope for a first middleware, and rotating maps in the memory store instead of scanning buckets per request is a good defualt. Happy with the umbrella export as remix/middleware/rate-limit. Anything left you want me to pick up, or is this good to land as-is? |
…t-middleware # Conflicts: # packages/remix/.changes/minor.remix.update-exports.md
Adds fixed-window rate limiting for Remix Fetch API servers through
remix/middleware/rate-limit.The API requires applications to choose an explicit client key because Fetch requests do not expose a trusted client address. Named policies allow global and route-specific limits to share a store and compose their response fields without collisions.
Stores expose one atomic fixed-window
increment()operation. The included memory store is an explicit, single-process option; multi-process or multi-host deployments can supply a shared store. Responses use the current IETF draft's namedRateLimitandRateLimit-Policystructured fields, withRetry-Afteron rejected requests.The package includes coverage for request boundaries, independent clients, policy composition, custom 429 responses, window rollover, invalid configuration and client keys, store failures, structured-field serialization, and memory-store rotation.