feat(disputes): compress large responses (gzip/deflate)#544
Merged
greatest0fallt1me merged 1 commit intoJul 26, 2026
Merged
Conversation
- Add src/middleware/compression.ts with compressResponse middleware using Node.js built-in zlib (no new dependencies required) - Support gzip and deflate encoding, selected via Accept-Encoding header - Prefer gzip over deflate when both are advertised by the client - Apply compression only to responses >= 1 KiB (COMPRESSION_THRESHOLD) to avoid CPU overhead on small payloads - Always set Vary: Accept-Encoding so HTTP caches store separate entries per encoding - Register compressResponse on the disputes router so all /api/markets/:id/disputes responses are eligible for compression - Add tests/compression.test.ts with unit and integration coverage: - selectEncoding helper (all encoding combinations and edge cases) - compressResponse middleware unit tests (header, res.json replacement) - Integration: gzip/deflate compress large payloads, round-trip verified - Integration: small payloads (< 1 KiB) remain uncompressed - Integration: identity/absent Accept-Encoding bypasses compression - Integration: disputes route verified end-to-end for both paths - COMPRESSION_THRESHOLD boundary tests (at and below threshold)
mohadon0
marked this pull request as draft
July 26, 2026 08:25
mohadon0
marked this pull request as ready for review
July 26, 2026 08:25
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.
Summary
Enables gzip and deflate response compression for the
/api/markets/:id/disputesendpoint. Large responses (≥ 1 KiB) are transparently compressed using Node.js's built-inzlibmodule — no new runtime dependencies are introduced.Changes
src/middleware/compression.ts(new)A self-contained Express middleware module exporting:
COMPRESSION_THRESHOLD1024bytes — minimum serialised response size before compression is appliedselectEncoding(acceptEncoding)Accept-Encodingand returns"gzip","deflate", or"identity". Prefers gzip.compressResponseRequestHandler— interceptsres.json(), compresses large payloads, sets appropriate headersKey behaviour:
Vary: Accept-Encodingis always set so HTTP caches (CDNs, proxies) store separate entries per encoding.COMPRESSION_THRESHOLDare forwarded to the originalres.json()unchanged.src/routes/disputes.ts(modified)Added
import { compressResponse } from "../middleware/compression"and registered it as router-level middleware:This applies compression to all current and future handlers on the disputes router without touching individual route handlers.
tests/compression.test.ts(new)625-line test file covering:
selectEncodingunitcompressResponseunitnext()called,Varyalways set,res.jsonreplaced only for compressed encodings, identity leaves originalres.jsonContent-Encodingheader,Content-Typepreserved,Content-Lengthsmaller than raw, status code preservedContent-Encoding,Varystill set, raw JSON body intactAccept-Encoding, identity explicit, unsupported (br)Varyalways on disputes, status preserved, error 409 unaffected, 401 auth still worksCOMPRESSION_THRESHOLDboundaryDesign decisions
No new dependencies. The implementation uses
zlibfrom the Node.js standard library. The popularcompressionnpm package uses the same underlying primitives and would add a transitive dependency for no functional gain here.Router-level middleware, not global. Compression is scoped to
disputesRouteronly — other routes are unaffected. A globalapp.use(compressResponse)could interfere with streaming responses (SSE, NDJSON export) and was intentionally avoided.Synchronous zlib.
gzipSync/deflateSyncare used rather than the async streaming variants becauseres.json()is a synchronous call and the payloads involved are bounded JSON objects. For streaming endpoints the async pipeline approach would be appropriate.Threshold at 1 KiB. The
COMPRESSION_THRESHOLD(1024 bytes) is a named, exported constant so it can be adjusted or overridden in tests without magic numbers.Files changed
How to verify
Resolves #52.