Skip to content

zstd request / response compression#836

Open
jstastny wants to merge 6 commits into
ClickHouse:mainfrom
jstastny:js/zstd-request-compression
Open

zstd request / response compression#836
jstastny wants to merge 6 commits into
ClickHouse:mainfrom
jstastny:js/zstd-request-compression

Conversation

@jstastny

Copy link
Copy Markdown

Summary

Adds zstd as a selectable codec for both directions of HTTP compression in
@clickhouse/client (Node.js):

  • request (insert) bodies — compression.request: "zstd"
  • response (read) bodies — compression.response: "zstd"

Fully backwards compatible: request: true / response: true still mean gzip.

Addresses the ZSTD item of #120.

Motivation

#120 (open since 2022) stalled on a concrete blocker: in 2023 there was no robust
Node compression library to lean on (node-lz4 didn't support modern Node, and
lz4-napi lacked streaming). That blocker no longer applies to zstd —
Node.js added zstd to the built-in zlib module in v22.15.0 / v23.8.0
(zlib.createZstdCompress / createZstdDecompress, as streaming Transforms).
So zstd needs no third-party dependency and reuses the exact streaming
pipeline gzip already uses.

zstd is also a better default than gzip for inserts: a similar-or-better ratio at
materially lower CPU. And per @mshustov's note on #120, ClickHouse decompresses
gzip single-threaded, so zstd lowers server-side ingest cost as well. This is most
impactful for write-heavy workloads (e.g. high-volume inserts over a metered
private link).

API

// gzip (unchanged)
createClient({ compression: { request: true,   response: true } })
// explicit codec
createClient({ compression: { request: "gzip", response: "gzip" } })
// zstd
createClient({ compression: { request: "zstd", response: "zstd" } })

compression.request and compression.response now accept
boolean | "gzip" | "zstd". true → gzip (back-compat); "zstd" selects zstd.

Implementation

  • client-common
    • Widened compression.request / compression.response (and the internal
      compress_request / decompress_response) to boolean | "gzip" | "zstd";
      new exported types RequestCompressionMethod / ResponseCompressionMethod.
    • withCompressionHeaders emits the matching Content-Encoding /
      Accept-Encoding (gzip or zstd).
  • client-node
    • Request: selects zlib.createZstdCompress() vs createGzip() in the request
      pipeline.
    • Response: handles Content-Encoding: zstd via zlib.createZstdDecompress().
      Decompression keys off the server's actual Content-Encoding, so it
      degrades gracefully if the server replies with gzip or no compression.
    • Fail fast: zstd requires Node.js >= 22.15; requesting it on an older
      runtime throws a clear error at client creation (@clickhouse/client
      supports node >=16).
  • client-web: unaffected — it doesn't compress request bodies, and the
    browser negotiates/decompresses responses.

Scope & notes

  • Only zstd from ZSTD, LZ4, BZ2, snappy compression support #120's list. lz4 / bz2 / snappy still require
    third-party native addons (the original blocker) and are out of scope here.
  • deflate and brotli are also native to Node's zlib and could be added
    later with the same pattern if there's interest.
  • Submitted as two commits (request, then response) for independent review —
    happy to squash.

Test plan

  • Unit tests (Node): request sets Content-Encoding: zstd and the body
    round-trips through zstdDecompress; response sends Accept-Encoding: zstd
    and a zstd-encoded response body is decompressed correctly. The gzip path is
    unchanged (back-compat test still passes).
  • tsc typecheck and eslint --max-warnings=0 clean across
    common / node / web; full build green.
  • Integration tests against a live server — extend the existing
    request_compression / response_compression suites with a zstd case
    (requires a ClickHouse version with zstd HTTP transport support, 22.10+).

Compatibility

  • No breaking changes; default behavior (gzip) is unchanged.
  • zstd needs Node.js >= 22.15 (guarded with a clear error) and a ClickHouse
    server that supports zstd HTTP Content-Encoding (server-side since 22.10).

Checklist

Delete items not relevant to your PR:

  • Unit and integration tests covering the common scenarios were added
  • A human-readable description of the changes was provided to include in CHANGELOG
  • For significant changes, documentation in https://github.com/ClickHouse/clickhouse-docs was updated with further explanations or tutorials

jstastny and others added 2 commits June 15, 2026 14:51
The `compression.request` option now accepts an explicit codec: `true`
(or "gzip") keeps gzip; "zstd" compresses the outgoing request body with
zstd via the built-in `zlib` zstd support (Node.js >= 22.15.0). zstd gives
a similar-or-better ratio than gzip at lower CPU cost, and ClickHouse
decompresses it faster server-side (gzip is decompressed single-threaded).

- client-common: widen `compression.request` to `boolean | "gzip" | "zstd"`
  ("true" => gzip, for backwards compatibility); thread the codec through
  `CompressionSettings.compress_request` and emit the matching
  `Content-Encoding` header. New exported `RequestCompressionMethod` type.
- client-node: select `Zlib.createZstdCompress()` vs `Zlib.createGzip()` in
  the request pipeline; fail fast at client creation with a clear error if
  "zstd" is requested on a Node.js without zlib zstd support.
- Web client is unaffected (it does not compress request bodies).
- Unit test + CHANGELOG entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Symmetric to the request-side change: `compression.response` now accepts an
explicit codec ("gzip" default when true, or "zstd"). When "zstd" is selected
the client sends `Accept-Encoding: zstd` and decompresses the response with the
built-in `zlib` zstd support (Node.js >= 22.15.0).

- client-common: widen `compression.response` / `decompress_response` to
  `boolean | "gzip" | "zstd"`; emit the matching `Accept-Encoding`; new exported
  `ResponseCompressionMethod` type. `withHttpSettings` accepts the codec (still
  only toggles `enable_http_compression`).
- client-node: handle `Content-Encoding: zstd` on responses via
  `Zlib.createZstdDecompress()`; thread the codec through the query path's
  response-compression negotiation. Decompression keys off the server's actual
  `Content-Encoding`, so it degrades gracefully against servers that reply with
  gzip or no compression.
- Web client unaffected (the browser negotiates/decompresses responses).
- Unit test + CHANGELOG entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 16, 2026 06:54
@CLAassistant

CLAassistant commented Jun 16, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds explicit "zstd" support for request/response compression in the Node.js client while keeping boolean compression options backward-compatible.

Changes:

  • Extend compression configuration/types to accept "gzip" or "zstd" in addition to booleans.
  • Implement zstd request compression and response decompression using Node’s built-in zlib zstd APIs.
  • Add unit tests and update changelog for the new zstd functionality.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
packages/client-node/src/connection/socket_pool.ts Adds zstd request body compression via zlib.createZstdCompress()
packages/client-node/src/connection/node_base_connection.ts Selects Accept-Encoding codec based on settings/config and adjusts decompression toggle
packages/client-node/src/connection/compression.ts Adds zstd response decompression via zlib.createZstdDecompress()
packages/client-node/src/config.ts Validates Node supports zstd request compression at client creation
packages/client-node/tests/unit/node_connection_compression.test.ts Adds tests for zstd request compression and response decompression
packages/client-common/src/utils/connection.ts Emits Accept-Encoding / Content-Encoding for gzip vs zstd
packages/client-common/src/index.ts Re-exports new compression method types
packages/client-common/src/connection.ts Introduces RequestCompressionMethod / ResponseCompressionMethod and widens compression settings types
packages/client-common/src/config.ts Updates public config option types/docs for "gzip" / "zstd"
CHANGELOG.md Documents new zstd compression options and Node version requirement

Comment on lines +131 to +140
if (
params.compression.compress_request === "zstd" &&
typeof Zlib.createZstdCompress !== "function"
) {
throw new Error(
"zstd request compression requires Node.js >= 22.15.0, where zstd " +
"support was added to the built-in zlib module. Upgrade Node.js, or " +
"use gzip request compression (`compression: { request: true }`) instead.",
);
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in b0bef48. Client creation now validates both compress_request and decompress_response for "zstd" through a shared validateCompressionSupport() helper with a single clear error message.

Comment on lines +394 to +398
const compressor =
params.enable_request_compression === "zstd"
? Zlib.createZstdCompress()
: Zlib.createGzip();
Stream.pipeline(bodyStream, compressor, request, callback);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b0bef48: the compressor is now built via a createRequestCompressor() helper that throws a clear error (instead of a TypeError) when zstd isn't available. For context, request compression comes from client config (compression.compress_request) and isn't settable per-request, so the creation-time validateCompressionSupport() check already guards this path — the helper is belt-and-suspenders.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: reverted to inline Zlib.createZstdCompress() / createGzip() selection in 9e06294 and dropped the createRequestCompressor helper. Request compression comes from client config and is validated at client creation, so it can never reach this path on an unsupported runtime - the helper was unnecessary abstraction.

Comment on lines 18 to 21
if (encoding === "gzip" || encoding === "zstd") {
const decompress =
encoding === "zstd" ? Zlib.createZstdDecompress() : Zlib.createGunzip();
return {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b0bef48 — the zstd branch now checks typeof Zlib.createZstdDecompress === "function" and returns a structured { error } (handled by the normal decompression error path) instead of crashing with ... is not a function.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: reverted the extra capability check here in 9e06294. zstd response decompression is only requested (Accept-Encoding: zstd) when decompress_response: "zstd", which is validated at client creation, so this path only sees zstd on runtimes that support it - the plain branch is sufficient.

Comment on lines +228 to +232
clickhouse_settings.enable_http_compression === 1
? this.params.compression.decompress_response === "zstd"
? "zstd"
: "gzip"
: false;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one is already correct: when enable_http_compression === 1 and decompress_response isn't "zstd", the ternary evaluates to "gzip" (truthy) — not false — so Accept-Encoding: gzip is still sent and the enforce-via-settings behavior is preserved. To make that unambiguous I rewrote it as an explicit let+if in b0bef48 (no behavior change; the codec defaults to gzip and is only zstd when explicitly configured on the client).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: reverted to the original ternary in 9e06294. As noted, it was already correct (it yields "gzip", not false, when enforcing via settings), so the refactor was unnecessary churn on correct code.

);
});

it('decompresses a zstd response and sends Accept-Encoding: zstd if response: "zstd"', async () => {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b0bef48 — both zstd tests are guarded with it.skipIf(!zstdSupported) (zstdSupported = typeof Zlib.createZstdCompress === "function"), so they skip on Node.js runtimes whose zlib has no zstd, e.g. the Node 20 entry in the CI matrix.

request.emit(
"response",
buildIncomingMessage({
body: Zlib.zstdCompressSync(Buffer.from(responseBody)),

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Covered by the same fix in b0bef48: this test is now guarded with it.skipIf(!zstdSupported), so it skips on Node runtimes without zlib zstd (< 22.15).

).toBe("gzip");
});

it('sends a zstd-compressed request if compress_request: "zstd"', async () => {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same fix in b0bef48 — guarded with it.skipIf(!zstdSupported), skipped on Node < 22.15.

next();
},
final() {
Zlib.zstdDecompress(chunks, (_err, result) => {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same fix in b0bef48 — guarded with it.skipIf(!zstdSupported), skipped on Node < 22.15.

@jstastny jstastny changed the title Js/zstd request compression zstd request / response compression Jun 16, 2026
… older Node

- Validate both `compress_request` and `decompress_response` for zstd at client
  creation (was request-only), via a new `validateCompressionSupport()` helper
  with a single clear error message.
- Guard the request-compressor and response-decompressor call sites so an
  unsupported runtime surfaces a clear error / structured decompression error
  instead of a `TypeError` (`createRequestCompressor()` helper; explicit zstd
  capability check in `decompressResponse()`).
- Clarify the response "enforce-via-settings" branch in node_base_connection
  (behavior unchanged: codec defaults to gzip; zstd only when explicitly
  configured on the client).
- Skip the zstd unit tests on Node.js runtimes whose `zlib` lacks zstd
  (`it.skipIf`), so the suite passes on the Node 20 entry of the CI matrix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jstastny jstastny requested a review from Copilot June 16, 2026 07:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Comment on lines +302 to +312
const request = new Stream.Writable({
write(chunk, encoding, next) {
chunks = Buffer.concat([chunks, chunk]);
next();
},
final() {
Zlib.zstdDecompress(chunks, (_err, result) => {
finalResult = result;
});
},
}) as ClientRequest;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in fa3c97b — the test's Writable.final(callback) now invokes callback(err) after decompression completes (propagating any error), so stream completion is signaled properly instead of relying on undefined semantics.

Comment on lines +320 to +325
// trigger stream pipeline
await sleep(0);
request.emit("socket", socketStub);
await sleep(100);

expect(finalResult!.toString("utf8")).toEqual(values);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in fa3c97b — replaced the fixed sleep(100) with awaiting a promise that resolves/rejects from the zstdDecompress callback, so the assertion is deterministic and not timing-dependent.

Comment thread packages/client-node/src/config.ts Outdated
nodeConfig: NodeClickHouseClientConfigOptions,
params: ConnectionParams,
) => {
validateCompressionSupport(params.compression);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in fa3c97b — a validateCompressionSupport describe covering: (1) throws for compress_request: "zstd" and for decompress_response: "zstd" when the corresponding Zlib.createZstd* is missing (simulated via Object.defineProperty, since zlib's exports are configurable: true, writable: false), and (2) does not throw for true / "gzip" / false.

…pressionSupport tests

- Make the zstd request-compression test deterministic: the Writable's
  `final(callback)` now invokes the callback (propagating errors), and the
  assertion awaits a promise resolved from `zstdDecompress` instead of a
  fixed `sleep(100)`.
- Add unit tests for `validateCompressionSupport`: throws for zstd request /
  response when the corresponding zlib zstd API is missing (simulated via
  `Object.defineProperty`), and does not throw for `true` / `"gzip"` / `false`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jstastny jstastny requested a review from Copilot June 16, 2026 07:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Comment on lines +349 to +364
function withMissingZlibFn(
name: "createZstdCompress" | "createZstdDecompress",
fn: () => void,
) {
const descriptor = Object.getOwnPropertyDescriptor(Zlib, name)!;
Object.defineProperty(Zlib, name, {
value: undefined,
configurable: true,
writable: true,
});
try {
fn();
} finally {
Object.defineProperty(Zlib, name, descriptor);
}
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved in 9e06294 by removing these zlib-monkey-patching tests entirely, along with the validateCompressionSupport helper they covered (now an inline guard at client creation). The it.skipIf(!zstdSupported) guards keep the suite green on Node 20.

Comment on lines +36 to +46
export function createRequestCompressor(
method: boolean | RequestCompressionMethod,
): Stream.Transform {
if (method === "zstd") {
if (typeof Zlib.createZstdCompress !== "function") {
throw new Error(ZSTD_UNSUPPORTED_MESSAGE);
}
return Zlib.createZstdCompress();
}
return Zlib.createGzip();
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved in 9e06294 - removed createRequestCompressor. The compressor is selected inline again and only ever with a truthy codec, so the false-returns-gzip case no longer exists.

Comment on lines +11 to +13
const ZSTD_UNSUPPORTED_MESSAGE =
"zstd compression requires Node.js >= 22.15.0, where zstd support was added " +
"to the built-in zlib module. Upgrade Node.js, or use gzip compression instead.";

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied in 9e06294 - the guard now uses a feature-detection message that leads with the missing zlib zstd APIs and includes the detected runtime (process.versions.node), rather than asserting a hardcoded minimum version.

…td guard

Reverts the helper/abstraction churn from the review rounds back toward the
original implementation, keeping only the genuinely-needed pieces:

- Inline the zstd capability guard at client creation, covering BOTH request
  and response (the one real gap), with a feature-detection error message.
- Remove the `validateCompressionSupport` and `createRequestCompressor`
  helpers; the request compressor is selected inline again (the creation-time
  guard makes it safe - request compression is client config, not per-request).
- Restore the original response-compression ternary in node_base_connection
  (it was already correct) and the plain `decompressResponse` branch.
- Tests: keep `it.skipIf` so the zstd cases skip on Node < 22.15; drop the
  zlib-monkey-patching unit tests that themselves caused a Node-20 regression.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@bobdevries

Copy link
Copy Markdown

Thanks @jstastny for raising!

@bobdevries

Copy link
Copy Markdown

Maybe this is not backward compatible, but I can imagine it makes sense to explicitly pass the codec and not mix booleans with strings in the payload.

@jstastny jstastny requested a review from Copilot June 16, 2026 09:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Comment on lines +18 to +20
if (encoding === "gzip" || encoding === "zstd") {
const decompress =
encoding === "zstd" ? Zlib.createZstdDecompress() : Zlib.createGunzip();

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch - fixed in 0ff391f. decompressResponse now only takes the zstd branch when typeof Zlib.createZstdDecompress === "function"; otherwise an unexpected Content-Encoding: zstd falls through to the existing Unexpected encoding structured error (same as any other unknown encoding) instead of throwing a TypeError mid-stream. So a client on a non-zstd runtime no longer crashes if a server/proxy returns zstd unsolicited.

stubClientRequest,
} from "../utils/http_stubs";

const zstdSupported = typeof Zlib.createZstdCompress === "function";

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 0ff391f - zstdSupported now checks every zstd zlib API the tests use (createZstdCompress, createZstdDecompress, zstdCompressSync, zstdDecompress), not just createZstdCompress.

Comment on lines +21 to +25
...(enable_response_compression
? {
"Accept-Encoding":
enable_response_compression === "zstd" ? "zstd" : "gzip",
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping this as a single-codec Accept-Encoding for now. compression.response: "zstd" is an explicit codec choice, and the decompression path already handles whatever the server actually returns (gzip/zstd/identity, with a clean error for anything unsupported). Advertising zstd, gzip would change the meaning of the explicit choice - you could silently get gzip - which I'd rather keep predictable. Happy to switch to q-value negotiation if you'd prefer it as the intended behavior.

Comment on lines +31 to +32
enable_response_compression?: boolean | ResponseCompressionMethod;
enable_request_compression?: boolean | RequestCompressionMethod;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are internal connection-params field names, not public API (the public option is compression.request / compression.response), and the boolean-or-codec convention is captured by their types. Renaming would ripple through several internal call sites for a cosmetic gain, so I'd prefer to keep them as-is to avoid the churn.

- decompressResponse: only take the zstd branch when zlib actually provides
  createZstdDecompress; otherwise fall through to the existing "Unexpected
  encoding" structured error. Prevents a TypeError mid-stream if a server or
  proxy returns Content-Encoding: zstd on a Node build without zstd support -
  even for clients that never configured zstd.
- tests: gate the zstd cases on every zstd zlib API they use
  (createZstdCompress / createZstdDecompress / zstdCompressSync / zstdDecompress),
  not just createZstdCompress.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jstastny jstastny requested a review from Copilot June 16, 2026 09:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Comment on lines 225 to +232
const { controller, controllerCleanup } = this.getAbortController(params);
// allows enforcing the compression via the settings even if the client instance has it disabled
const enableResponseCompression =
clickhouse_settings.enable_http_compression === 1;
clickhouse_settings.enable_http_compression === 1
? this.params.compression.decompress_response === "zstd"
? "zstd"
: "gzip"
: false;
Comment on lines 393 to +398
if (params.enable_request_compression) {
Stream.pipeline(bodyStream, Zlib.createGzip(), request, callback);
const compressor =
params.enable_request_compression === "zstd"
? Zlib.createZstdCompress()
: Zlib.createGzip();
Stream.pipeline(bodyStream, compressor, request, callback);
Comment on lines +131 to +145
// zstd needs Node.js >= 22.15.0 (zstd in the built-in zlib); fail fast with a
// clear error rather than a TypeError deep in a later insert/query.
if (
(params.compression.compress_request === "zstd" &&
typeof Zlib.createZstdCompress !== "function") ||
(params.compression.decompress_response === "zstd" &&
typeof Zlib.createZstdDecompress !== "function")
) {
throw new Error(
"zstd compression is not supported by this Node.js runtime (v" +
process.versions.node +
"): the built-in zlib module does not provide the zstd APIs (added " +
"in Node.js 22.15.0). Use gzip compression instead.",
);
}
@jstastny

Copy link
Copy Markdown
Author

Maybe this is not backward compatible, but I can imagine it makes sense to explicitly pass the codec and not mix booleans with strings in the payload.

Thanks @bobdevries — you're right that overloading one field with boolean | string isn't the cleanest design; a codec-only field would be tidier on its own merits.

For me it comes down to the trade-off against backward compatibility. compression: { request?: boolean } / { response?: boolean } is the current public API, so going codec-only would break every existing request: true / response: true caller and force a config change on upgrade. For an established, widely-used option that felt like a steep price for the type-purity gain, so I leaned toward widening the existing type (keeping true = gzip) rather than replacing it.

I don't feel strongly enough to override your call on the repo's conventions, though. If you'd prefer the codec-only shape and want to treat it as a breaking change for a future major, I'm happy to switch the types/guard/tests over. My default, unless you feel strongly, would be to keep it backward compatible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants