### Install @fastify/compress Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/README.md Install the @fastify/compress plugin using npm. ```bash npm install @fastify/compress ``` -------------------------------- ### Minimal Fastify Compress Setup Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md This is the most basic setup for @fastify/compress. It enables compression with default settings, automatically compressing responses that meet the threshold using the best available algorithm. ```javascript import fastify from 'fastify' import compress from '@fastify/compress' const app = fastify() await app.register(compress) app.get('/', (req, reply) => { reply.send({ message: 'Compressed response' }) }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Configure Compression Encodings Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/types.md Example of configuring supported encodings for the plugin and request encodings for routes. ```typescript // In plugin options await app.register(compress, { encodings: ['gzip', 'deflate'], requestEncodings: ['gzip'] }) // In route options app.get('/api', { compress: { encodings: ['br', 'gzip'] } }, handler) ``` -------------------------------- ### Route Compress Options Example Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/types.md Configure compression settings for a specific route, including allowed encodings, threshold, and zlib options. ```javascript app.get('/fast', { compress: { encodings: ['gzip'], threshold: 2048, zlibOptions: { level: 1 } } }, handler) ``` ```javascript app.get('/high-quality', { compress: { brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 11 } } } }, handler) ``` -------------------------------- ### Combined Route Compression and Decompression Usage Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/types.md Example demonstrating how to configure both compression and decompression settings for a single route. ```javascript app.post('/upload', { decompress: { requestEncodings: ['gzip', 'deflate'] } }, (request, reply) => { // Request is automatically decompressed reply.send({ received: request.body }) }) ``` ```javascript app.get('/download', { compress: { threshold: 512, encodings: ['br', 'gzip'] } }, (request, reply) => { reply.compress(largeDataset) }) ``` -------------------------------- ### Usage Examples for reply.compress() Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/types.md Demonstrates how to use reply.compress() with different input types including strings, buffers, typed arrays, iterables, and async iterables. ```javascript app.get('/data', (request, reply) => { // String reply.compress('text content') // Buffer reply.compress(Buffer.from('binary data')) // Typed array reply.compress(new Uint8Array([1, 2, 3])) // Iterable reply.compress(['chunk1', 'chunk2']) // Async iterable reply.compress(asyncGenerator()) }) ``` -------------------------------- ### Integrate Compression Metrics Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md This example demonstrates how to collect and expose compression-related metrics. It uses an 'onSend' hook to track responses and compressed data, and exposes a '/metrics' endpoint to serve the collected data. ```javascript let compressionMetrics = { responses: 0, compressed: 0, bytesIn: 0, bytesOut: 0 } app.addHook('onSend', (request, reply, payload, next) => { compressionMetrics.responses++ if (reply.getHeader('content-encoding')) { compressionMetrics.compressed++ } next() }) app.get('/metrics', (req, reply) => { reply.send(compressionMetrics) }) ``` -------------------------------- ### Configure zlib Compression Parameters Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Fine-tune gzip and deflate compression using parameters like level, memory level, and strategy. This example sets a balanced compression level. ```javascript const zlib = require('node:zlib') await app.register(compress, { zlibOptions: { // Compression level (0-9): 0=no compression, 6=default, 9=max level: 6, // Memory level (1-9): Affects memory usage and speed memLevel: 8, // Strategy: HUFFMAN_ONLY, RLE, FIXED, DEFAULT strategy: zlib.constants.Z_DEFAULT_STRATEGY } }) ``` -------------------------------- ### Example Usage of isZstd Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/utils.md Demonstrates how to use the isZstd function with compressed and plain text buffers. Requires Node.js zlib module support for zstd. ```javascript const zlib = require('node:zlib') const { isZstd } = require('./lib/utils') if (typeof zlib.createZstdCompress === 'function') { const zstdData = zlib.zstdCompressSync(Buffer.from('test')) console.log(isZstd(zstdData)) // true } console.log(isZstd(Buffer.from('plain text'))) ``` -------------------------------- ### Customize Encoding Priority (Deflate/Gzip) Source: https://github.com/fastify/fastify-compress/blob/main/README.md Specify the order of preferred compression encodings. This example prioritizes deflate over gzip. ```javascript await fastify.register( import('@fastify/compress'), // Only support gzip and deflate, and prefer deflate to gzip { encodings: ['deflate', 'gzip'] } ) ``` -------------------------------- ### Tune Compression with brotliOptions and zlibOptions Source: https://github.com/fastify/fastify-compress/blob/main/README.md Pass options directly to native Node.js zlib methods to fine-tune compression. This example sets Brotli mode and quality, and zlib level. ```javascript server.register(fastifyCompress, { brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT, // useful for APIs that primarily return text [zlib.constants.BROTLI_PARAM_QUALITY]: 4, // default is 4, max is 11, min is 0 }, }, zlibOptions: { level: 6, // default is typically 6, max is 9, min is 0 } }); ``` -------------------------------- ### Enable Specific Request Encodings Source: https://github.com/fastify/fastify-compress/blob/main/README.md Configure which compression algorithms are supported for request decompression. This example enables zstd, brotli, and gzip. ```javascript // Example with zstd support for request decompression (Node.js 22.15+/23.8+) await fastify.register( import('@fastify/compress'), // Support zstd, brotli and gzip for request decompression { requestEncodings: ['zstd', 'br', 'gzip'] } ) ``` -------------------------------- ### Complete Fastify Compress Setup Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/00-START-HERE.md Configure global compression and decompression settings, including response compression thresholds, supported encodings, and custom types. Also demonstrates per-route overrides for compression options and disabling compression/decompression for specific routes. ```javascript import fastify from 'fastify' import compress from '@fastify/compress' import zlib from 'node:zlib' const app = fastify() await app.register(compress, { // Global settings globalCompression: true, globalDecompression: true, // Response compression threshold: 1024, encodings: ['zstd', 'br', 'gzip'], customTypes: /x-protobuf$/, // Request decompression requestEncodings: ['zstd', 'br', 'gzip'], // Optimization brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 4 } }, // Error handling onUnsupportedEncoding: (encoding, req, reply) => { reply.code(406) return `Unsupported: ${encoding}` } }) // Per-route overrides app.get('/fast', { compress: { zlibOptions: { level: 1 } } }, handler) app.get('/archive', { compress: { brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 11 } }} }, handler) app.post('/webhook', { compress: false, // This route doesn't compress decompress: false // This route doesn't decompress }, handler) await app.listen({ port: 3000 }) ``` -------------------------------- ### Basic Fastify Compress Setup Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/00-START-HERE.md Register the compress plugin with Fastify to enable automatic response compression. Responses are compressed if they are larger than 1024 bytes and the Content-Type is compressible. Compression is skipped if the client does not support it. ```javascript import fastify from 'fastify' import compress from '@fastify/compress' const app = fastify() await app.register(compress) app.get('/', (req, reply) => { reply.send({ message: 'Hello' }) // Automatically compressed }) await app.listen({ port: 3000 }) ``` -------------------------------- ### Environment-Specific Compression Configuration Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Dynamically configure compression settings based on the environment (e.g., development vs. production). This example disables compression in development for easier debugging and enables it with specific settings in production. ```javascript async function setupCompression(fastify) { if (process.env.NODE_ENV === 'development') { // No compression in development for debugging await fastify.register(compress, { globalCompression: false }) } else { // Full compression in production await fastify.register(compress, { threshold: 512, encodings: ['zstd', 'br', 'gzip'], brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 4 } } }) } } await setupCompression(app) ``` -------------------------------- ### Configure Fastify Compress Plugin Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/types.md Comprehensive example of configuring the Fastify Compress plugin with various options. This includes global settings, compression and decompression preferences, custom type detection using a RegExp, and specific brotli/zlib options. ```javascript await app.register(compress, { // Global settings global: true, globalCompression: true, globalDecompression: true, // Compression threshold: 1024, encodings: ['zstd', 'br', 'gzip'], customTypes: /x-protobuf$/, removeContentLengthHeader: true, // Decompression requestEncodings: ['gzip', 'deflate'], // Options brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 4 } }, zlibOptions: { level: 6 } }) ``` -------------------------------- ### Build Route Compression Setup Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/api-reference-internal-functions.md Attaches compression hooks to a specific route. This function is called by the onRoute hook to configure compression behavior for individual routes. ```javascript function buildRouteCompress(_fastify, params, routeOptions, decorateOnly) ``` -------------------------------- ### Fastify Compress: Conditional Encoding by Environment Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Dynamically configure @fastify/compress encodings based on the environment. This example uses advanced algorithms like zstd and br in production for better performance, while falling back to gzip in development. ```javascript const isProduction = process.env.NODE_ENV === 'production' const encodings = isProduction ? ['zstd', 'br', 'gzip'] // Advanced algorithms in production : ['gzip'] // Simple setup in development await app.register(compress, { encodings }) ``` -------------------------------- ### Customize Encoding Priority (Zstd/Brotli/Gzip) Source: https://github.com/fastify/fastify-compress/blob/main/README.md Customize encoding priority with newer compression algorithms like zstd and brotli. This example prefers zstd, then brotli, then gzip. ```javascript // Example with zstd support (Node.js 22.15+/23.8+) await fastify.register( import('@fastify/compress'), // Prefer zstd, fallback to brotli, then gzip { encodings: ['zstd', 'br', 'gzip'] } ) ``` -------------------------------- ### compress Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/api-reference-internal-functions.md Factory function that returns the actual compress method bound to compression params. This is what gets assigned to `reply.compress`. ```APIDOC ## compress(params) ### Description Factory function that returns the actual compress method bound to compression params. This is what gets assigned to `reply.compress`. ### Function Signature ```javascript function compress(params) ``` ### Parameters - **params** (Object) - Compression parameters ``` -------------------------------- ### Example Usage of isStream Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/utils.md Shows how to use the isStream function with various data types including file streams, readable streams, strings, and buffers. ```javascript const fs = require('node:fs') const { Readable } = require('node:stream') const { isStream } = require('./lib/utils') console.log(isStream(fs.createReadStream('file.txt'))) // true console.log(isStream(Readable.from(['a', 'b']))) // true console.log(isStream('string')) // false console.log(isStream(Buffer.from('data'))) ``` -------------------------------- ### Route Decompress Options Example Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/types.md Configure request decompression settings for a specific route, specifying allowed request encodings and forcing a particular encoding. ```javascript app.post('/api/data', { decompress: { requestEncodings: ['gzip'], forceRequestEncoding: 'gzip' } }, handler) ``` -------------------------------- ### Register Compress Plugin with Custom Types Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/types.md Example of registering the compress plugin and providing a custom function to handle content types for compression. This allows compression of non-standard types like protobuf or custom binary formats. ```javascript await app.register(compress, { customTypes: (contentType) => { // Compress custom protobuf type if (contentType.includes('x-protobuf')) return true // Compress custom binary formats if (contentType.includes('application/custom')) return true return false } }) ``` -------------------------------- ### Conditional Compression Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/README.md Conditionally compress responses based on request headers. This example skips compression if the 'x-no-compression' header is present. ```javascript app.get('/api', (request, reply) => { if (request.headers['x-no-compression']) { reply.send(data) } else { reply.compress(data) } }) ``` -------------------------------- ### Configure Brotli Compression Parameters Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Fine-tune Brotli compression using various parameters like quality, mode, and window size. This example sets a higher quality and larger block size for potentially better compression. ```javascript const zlib = require('node:zlib') await app.register(compress, { brotliOptions: { params: { // Quality (0-11): Higher = better compression, slower // Default 4 balances speed and ratio per Cloudflare benchmarks [zlib.constants.BROTLI_PARAM_QUALITY]: 6, // Mode: 0=generic, 1=text, 2=binary [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT, // Window size (10-24): Larger = better compression, more memory [zlib.constants.BROTLI_PARAM_LGWIN]: 22, // Block size (16-24): Larger = slower compression, better ratio [zlib.constants.BROTLI_PARAM_LGBLOCK]: 24 } } }) ``` -------------------------------- ### Custom Content Types (Regex) Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Register custom content types for compression using a regular expression. This example compresses responses ending with `x-protobuf` or containing `custom-binary`. ```javascript await app.register(compress, { customTypes: /x-protobuf$|custom-binary/ }) ``` -------------------------------- ### Override Compression Encoding Priority Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/README.md Customize the order of compression encodings supported by the client. This example registers the compress plugin with a specific priority for gzip, br, and deflate. ```javascript await app.register(compress, { encodings: ['gzip', 'br', 'deflate'] // Custom order }) ``` -------------------------------- ### Per Route Decompression Options Source: https://github.com/fastify/fastify-compress/blob/main/README.md Configure specific decompression options for a route using the `decompress` property in the route's configuration. This example forces gzip decompression and allows custom zlib implementations. ```javascript await fastify.register( import('@fastify/compress'), { global: false } ) // Always decompress using gzip fastify.get('/custom-route', { decompress: { forceRequestEncoding: 'gzip', zlib: { createBrotliDecompress: () => createYourCustomBrotliDecompress(), createGunzip: () => createYourCustomGunzip(), createInflate: () => createYourCustomInflate() } } }, (req, reply) => { // ... }) ``` -------------------------------- ### Custom Content Types (Function) Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Define custom compression logic using a function that inspects the `contentType`. This example compresses all `application/*` types, excludes streaming types, and defaults to not compressing others. ```javascript await app.register(compress, { customTypes: (contentType) => { // Always compress application types if (contentType.startsWith('application/')) { return true } // Exclude streaming types if (contentType.includes('event-stream')) { return false } // Default behavior via mime-db return false } }) ``` -------------------------------- ### Detect Zstandard Compressed Data Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/utils.md Checks if a buffer starts with the Zstandard magic number. Useful for identifying zstd compressed data before decompression. ```javascript function isZstd(buffer) { return ( typeof buffer === 'object' && buffer !== null && buffer.length > 3 && // Zstd magic number: 0xFD2FB528 (little-endian bytes) buffer[0] === 0x28 && buffer[1] === 0xb5 && buffer[2] === 0x2f && buffer[3] === 0xfd ) } ``` -------------------------------- ### Limit Supported Request Encodings Source: https://github.com/fastify/fastify-compress/blob/main/README.md Restrict the accepted request encodings by providing an array of compression tokens to the `requestEncodings` option. This example only allows gzip. ```javascript await fastify.register( import('@fastify/compress'), // Only support gzip { requestEncodings: ['gzip'] } ) ``` -------------------------------- ### Importing Utility Functions Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/utils.md Demonstrates how to import utility functions into the main Fastify plugin (index.js). ```javascript const { isStream, isGzip, isDeflate, intoAsyncIterator, isWebReadableStream, isFetchResponse, webStreamToNodeReadable } = require('./lib/utils') ``` -------------------------------- ### Decorate Reply with Compress Method Placeholder Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/hooks-and-integration.md Initializes the `compress` method on the FastifyReply object as a null placeholder. The actual method is bound later. ```javascript fastify.decorateReply('compress', null) ``` -------------------------------- ### Fastify Compress Plugin Entry Point Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/README.md This is the main entry point for the Fastify Compress plugin, used for registration with Fastify. It specifies the Fastify version compatibility and plugin name. ```javascript module.exports = fp(fastifyCompress, { fastify: '5.x', name: '@fastify/compress' }) module.exports.default = fastifyCompress module.exports.fastifyCompress = fastifyCompress ``` -------------------------------- ### Detect Gzip Data with isGzip() Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/utils.md Use this function to check if a Buffer starts with the gzip magic number. It requires the buffer to be at least 3 bytes long. ```javascript function isGzip(buffer) { return ( typeof buffer === 'object' && buffer !== null && buffer.length > 2 && // ID1 (first identification byte) buffer[0] === 0x1f && // ID2 (second identification byte) buffer[1] === 0x8b && // CM (compression method byte - must be 0x08 for deflate) buffer[2] === 0x08 ) } ``` ```javascript const zlib = require('node:zlib') const { isGzip } = require('./lib/utils') const gzipData = zlib.gzipSync(Buffer.from('test')) console.log(isGzip(gzipData)) // true console.log(isGzip(Buffer.from('plain text'))) ``` -------------------------------- ### Configure High-Performance Compression APIs Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Sets up Fastify Compress for high performance by using faster compression with a lower compression ratio. Only enables gzip encoding. ```javascript // Fast compression, lower ratio await app.register(compress, { threshold: 2048, encodings: ['gzip'], zlibOptions: { level: 1 } }) ``` -------------------------------- ### Run Tests with npm Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/README.md Use these npm commands to run various test suites, including all tests, unit tests, TypeScript type checking, and coverage reports. ```bash npm test # Run all tests ``` ```bash npm run test:unit # Unit tests ``` ```bash npm run test:typescript # Type checking ``` ```bash npm run test:coverage # Coverage report ``` -------------------------------- ### Configure Compression for Static Files Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Configure compression for static file servers, with a lower threshold and options to inflate if deflated. Brotli compression quality is set to maximum. ```javascript await app.register(compress, { threshold: 512, inflateIfDeflated: true, brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 11 } } }) ``` -------------------------------- ### Configure Static Site High Compression Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/00-START-HERE.md Register the compress plugin for static sites, configuring Brotli with the maximum quality level for the best compression ratio. ```javascript await app.register(compress, { brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 11 } } }) ``` -------------------------------- ### Custom Error Handling for Unsupported Encoding Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/api-reference-reply-compress.md Registers a custom handler for unsupported encodings during compression. This example disables global compression for the plugin and applies custom error handling. ```javascript await app.register(compress, { global: false, onUnsupportedEncoding: (encoding, request, reply) => { reply.code(406) return `Server does not support ${encoding}` } }) app.get('/custom', (request, reply) => { reply.compress(fs.createReadStream('./data.txt')) }) ``` -------------------------------- ### Per-Route Compression Configuration Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/api-reference-reply-compress.md Shows how to configure compression settings on a per-route basis, including setting a custom compression threshold, overriding supported encodings, and providing custom Brotli or zlib options. ```APIDOC ## Per-Route Compression Configuration ### Description Allows overriding compression settings for individual routes. ### Route Options - `compress`: An object containing compression specific options for the route. - `threshold`: Minimum payload size in bytes for compression to be applied. - `encodings`: An array of supported encodings for this specific route. - `customTypes`: A function or regex for custom content-type detection. - `brotliOptions`: Options for Brotli compression. - `params`: Brotli compression parameters, e.g., `zlib.constants.BROTLI_PARAM_QUALITY`. - `zlibOptions`: Options for zlib (gzip/deflate) compression. - `inflateIfDeflated`: Boolean to auto-decompress pre-compressed bodies for incompatible clients. - `removeContentLengthHeader`: Boolean to keep the `Content-Length` header if it is set. - `zlib`: Custom zlib implementation or override methods. ### Example: Custom Threshold ```javascript app.get('/large-file', { compress: { threshold: 10240 } // Only compress if > 10KB }, (request, reply) => { reply.compress(fs.createReadStream('./large-data.json')) }) ``` ### Example: Custom Brotli Options ```javascript import zlib from 'node:zlib' app.get('/fast', { compress: { brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 1 // Faster, lower compression } } } }, (request, reply) => { reply.compress({ data: 'Quick response' }) }) ``` ### Example: Disable Content-Length Header Removal ```javascript app.get('/with-length', { compress: { removeContentLengthHeader: false } }, (request, reply) => { const buffer = Buffer.from('Known size data') reply.compress(buffer) }) ``` ``` -------------------------------- ### Get Encoding Header Function Signature Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/api-reference-internal-functions.md Details the signature for the getEncodingHeader utility function. It negotiates the best encoding from the request's 'accept-encoding' header based on supported encodings. ```javascript function getEncodingHeader(encodings, request) ``` -------------------------------- ### Global Compress Configuration Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/README.md Configure compression globally for all routes, specifying thresholds and supported encodings like Brotli and Gzip. ```javascript await app.register(compress, { threshold: 1024, encodings: ['br', 'gzip'], brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 4 } } }) ``` -------------------------------- ### Correct Compress Route Option Usage Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/errors.md Shows the correct ways to configure the 'compress' route option, either by disabling it with 'false' or providing custom options as an object. ```javascript // ✅ CORRECT - Disable app.get('/api', { compress: false }, handler) // ✅ CORRECT - Custom options app.get('/api', { compress: { threshold: 512 } }, handler) ``` -------------------------------- ### Project Structure Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/README.md This snippet outlines the directory structure of the @fastify/compress project, detailing the location of main implementation files, utilities, type definitions, and tests. ```tree @fastify/compress/ ├── index.js # Main plugin implementation ├── lib/ │ └── utils.js # Compression detection and stream utilities ├── types/ │ ├── index.d.ts # TypeScript type definitions │ └── index.tst.ts # TypeScript type tests ├── test/ │ ├── global-compress.test.js │ ├── global-decompress.test.js │ ├── routes-compress.test.js │ ├── routes-decompress.test.js │ └── regression/ └── package.json ``` -------------------------------- ### Route Options for Compression Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/types.md Extends `RouteShorthandOptions` and `RouteOptions` to include configuration for compression and decompression at the route level. ```APIDOC ## Route Options for Compression ### Description Allows configuring compression and decompression options for individual routes. ### Interface Extensions #### RouteShorthandOptions ```typescript interface RouteShorthandOptions { compress?: RouteCompressOptions | false; decompress?: RouteDecompressOptions | false; } ``` #### RouteOptions ```typescript interface RouteOptions { compress?: RouteCompressOptions | false; decompress?: RouteDecompressOptions | false; } ``` ### Parameters - **compress** (RouteCompressOptions | false) - Optional. Configuration for response compression. Set to `false` to disable. - **decompress** (RouteDecompressOptions | false) - Optional. Configuration for request decompression. Set to `false` to disable. ``` -------------------------------- ### PreParsing Hook Implementation Pattern Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/hooks-and-integration.md Illustrates how to integrate the preParsing hook into Fastify route options. This pattern handles adding the hook to existing preParsing arrays or creating a new one if none exists. The hook itself checks for content encoding, validates it, and pipes the raw stream through a decompressor if necessary. ```javascript if (Array.isArray(routeOptions.preParsing)) { routeOptions.preParsing.unshift(preParsing) } else if (typeof routeOptions.preParsing === 'function') { routeOptions.preParsing = [preParsing, routeOptions.preParsing] } else { routeOptions.preParsing = [preParsing] } function preParsing(request, _reply, raw, next) { let encoding = params.forceEncoding if (!encoding) { encoding = request.headers['content-encoding'] } if (!encoding) { return next(null, raw) } if (!params.encodings.includes(encoding)) { let errorPayload if (params.onUnsupportedRequestEncoding) { try { errorPayload = params.onUnsupportedRequestEncoding(encoding, request) } catch { errorPayload = undefined } } if (!errorPayload) { errorPayload = new InvalidRequestEncodingError(encoding) } return next(errorPayload) } if (encoding === 'identity') { return next(null, raw) } const decompresser = params.decompressStream[encoding]() decompresser.receivedEncodedLength = 0 decompresser.on('error', onDecompressError.bind(this, request, params, encoding)) decompresser.pause() raw.on('data', trackEncodedLength.bind(decompresser)) raw.on('end', removeEncodedLengthTracking) pipeline(raw, decompresser, () => { // Cleanup callback }) next(null, decompresser) } ``` -------------------------------- ### Fast zlib Compression Configuration Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Configure zlib for fast compression by setting the compression level to 1. ```javascript zlibOptions: { level: 1 } ``` -------------------------------- ### Configure Compression in Route Options Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/types.md Extends `RouteShorthandOptions` and `RouteOptions` to include `compress` and `decompress` properties for configuring compression behavior per route. ```typescript declare module 'fastify' { export interface RouteShorthandOptions { compress?: RouteCompressOptions | false; decompress?: RouteDecompressOptions | false; } export interface RouteOptions { compress?: RouteCompressOptions | false; decompress?: RouteDecompressOptions | false; } } ``` -------------------------------- ### Fastify Compress: Support Only gzip Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Configure @fastify/compress to only support the `gzip` encoding and `identity` (no compression). This simplifies configuration when the client base exclusively supports gzip. ```javascript await app.register(compress, { encodings: ['gzip', 'identity'] }) ``` -------------------------------- ### Configure Minimal Compression Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Apply minimal compression by disabling global compression. This requires explicit configuration for compression to be applied. ```javascript await app.register(compress, { global: false }) // Only compress where explicitly configured ``` -------------------------------- ### Scope-Based Compression Configuration Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/README.md Configure compression settings within specific scopes using `app.register`. This allows for different compression behaviors in different parts of the application. ```javascript app.register(async (fastify) => { await fastify.register(compress, { globalCompression: true, threshold: 512 }) fastify.get('/api/*', handler }) app.register(async (fastify) => { await fastify.register(compress, { globalCompression: false }) fastify.get('/static/*', handler }) ``` -------------------------------- ### Balanced zlib Compression Configuration Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Configure zlib for balanced compression, using the default compression level of 6. ```javascript zlibOptions: { level: 6 } ``` -------------------------------- ### Fastify Compress: Prefer Brotli Over gzip Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Configure @fastify/compress to prioritize Brotli (`br`) over gzip for better compression ratios on modern clients that support it. The order in the `encodings` array determines the preference. ```javascript await app.register(compress, { encodings: ['br', 'gzip', 'deflate'] }) ``` -------------------------------- ### Provide Custom zlib Implementation Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Override the default zlib module with a custom implementation. This is useful for custom compression logic or alternative libraries. ```javascript import zlib from 'node:zlib' import customZlib from './my-custom-zlib' await app.register(compress, { zlib: customZlib }) ``` -------------------------------- ### Parameter Processing Flow Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/INDEX.md Illustrates the flow of options processing for compression and decompression parameters, from plugin options to route-specific hooks. ```text Plugin Options → processCompressParams()/processDecompressParams() → globalCompressParams/globalDecompressParams ↓ onRoute Hook → Per-route options → mergedParams ↓ buildRouteCompress/buildRouteDecompress → hooks attached to route ``` -------------------------------- ### Create Compression Stream - zipStream Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/api-reference-internal-functions.md Creates a compression stream that auto-detects pre-compressed data. It uses peek-stream to inspect the first 10 bytes and either returns a pass-through stream if already compressed or the appropriate compression stream for the selected encoding. ```javascript function zipStream(deflate, encoding) ``` -------------------------------- ### Lint Code with npm Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/README.md Execute these npm commands for code style checking and automatic fixing of linting issues. ```bash npm run lint # Check code style ``` ```bash npm run lint:fix # Auto-fix style issues ``` -------------------------------- ### Use Custom Compression Level Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/INDEX.md Configure a custom compression level for a specific route by providing `zlibOptions` with the desired `level` in the route's `compress` configuration. ```javascript app.get('/report', { compress: { zlibOptions: { level: 9 } } }, handler) ``` -------------------------------- ### Fastify Compress onRequest Hook Code Pattern Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/hooks-and-integration.md This code pattern demonstrates how to correctly push the `onRequest` hook handler into the route options, ensuring compatibility with existing handlers or initializing it if none exist. It also shows the initialization of the `compressFn`. ```javascript if (Array.isArray(routeOptions.onRequest)) { routeOptions.onRequest.push(onRequest) } else if (typeof routeOptions.onRequest === 'function') { routeOptions.onRequest = [routeOptions.onRequest, onRequest] } else { routeOptions.onRequest = [onRequest] } const compressFn = compress(params) function onRequest(_req, reply, next) { reply.compress = compressFn next() } ``` -------------------------------- ### Maximum zlib Compression Configuration Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Configure zlib for maximum compression by setting the compression level to 9. ```javascript zlibOptions: { level: 9 } ``` -------------------------------- ### Configure Compression for Memory-Constrained Environments Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Reduces compression quality and memory usage for Brotli and zlib to conserve memory in constrained environments. ```javascript // Reduce compression quality to save memory await app.register(compress, { brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 1, [zlib.constants.BROTLI_PARAM_LGWIN]: 20 } }, zlibOptions: { level: 1, memLevel: 4 } }) ``` -------------------------------- ### Configure Supported Encodings Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Specifies the compression encodings to support for response compression, in priority order. The plugin uses content negotiation to select the best encoding supported by the client. ```javascript // Only support gzip and deflate, prefer deflate await app.register(compress, { encodings: ['deflate', 'gzip'] }) // Prefer brotli over gzip await app.register(compress, { encodings: ['br', 'gzip', 'deflate'] }) // Enable zstd if Node.js supports it (22.15+/23.8+) await app.register(compress, { encodings: ['zstd', 'br', 'gzip', 'deflate'] }) ``` -------------------------------- ### Configure Compression Threshold Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/00-START-HERE.md Register the compress plugin with a global compression threshold. Route-specific options can override this global setting. ```javascript await app.register(compress, { threshold: 1024 }) app.get('/api', { compress: { threshold: 2048 } }, handler) app.get('/data', handler) app.get('/metrics', { compress: false }, handler) ``` -------------------------------- ### Module Exports from Utils Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/utils.md Lists all utility functions exported from the lib/utils.js file. ```javascript module.exports = { isZstd, isGzip, isDeflate, isStream, intoAsyncIterator, isWebReadableStream, isFetchResponse, webStreamToNodeReadable } ``` -------------------------------- ### Register Compress Plugin Globally Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Enables global compression and decompression on all routes by default. Specific routes can opt-out using `compress: false`. ```javascript await app.register(compress, { global: true }) ``` -------------------------------- ### Manual Compression with Streams Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/README.md Manually compress a response stream using `reply.compress()`, useful for large files or when compression needs to be controlled explicitly. ```javascript import fs from 'node:fs' app.get('/file', { compress: false }, (request, reply) => { // Manual compression via reply.compress() reply.compress(fs.createReadStream('./large-file.json')) }) ``` -------------------------------- ### Configure Production API Compression Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/00-START-HERE.md Register the compress plugin for production APIs, specifying 'gzip' as the only supported encoding and setting a low zlib compression level for faster compression. ```javascript await app.register(compress, { encodings: ['gzip'], zlibOptions: { level: 1 } }) ``` -------------------------------- ### Stream Large Files with Fastify Compress Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Use this pattern to efficiently stream large files to clients. The `reply.compress()` method handles compression automatically. ```javascript app.get('/download/:file', (req, reply) => { const filePath = `/data/${req.params.file}` reply.compress(fs.createReadStream(filePath)) }) ``` -------------------------------- ### Configure High-Performance Compression Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Use this configuration for high-performance scenarios, setting a compression threshold and enabling gzip encoding with a low zlib compression level. Global decompression is disabled to only handle GET-like requests. ```javascript await app.register(compress, { threshold: 2048, encodings: ['gzip'], zlibOptions: { level: 1 }, globalDecompression: false // Only handle GET-like requests }) ``` -------------------------------- ### Aggressive Compression (Compress Everything) Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Use a threshold of 0 to compress all responses, regardless of size. Be aware that small responses may increase in size due to compression overhead. ```javascript await app.register(compress, { threshold: 0 }) ``` -------------------------------- ### Compressing Different Response Types Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/api-reference-reply-compress.md Demonstrates how to use the `reply.compress()` method to compress various data types including file streams, JSON objects, plain strings, Buffers, Fetch API Responses, and Web ReadableStreams. ```APIDOC ## Compress a file stream ### Description Compresses a file stream. ### Method ```javascript reply.compress(fs.createReadStream('./package.json')) ``` ## Compress a JSON object ### Description Compresses a JSON object. ### Method ```javascript reply.compress({ message: 'Hello', data: [1, 2, 3] }) ``` ## Compress a plain string ### Description Compresses a plain string. ### Method ```javascript reply.compress('This is a long string that will be compressed') ``` ## Compress a Buffer ### Description Compresses a Buffer. ### Method ```javascript const buffer = Buffer.from('Binary data here') reply.compress(buffer) ``` ## Compress a Fetch API Response ### Description Compresses a Fetch API Response. ### Method ```javascript const response = new Response('Hello from Fetch Response') reply.compress(response) ``` ## Compress a Web ReadableStream ### Description Compresses a Web ReadableStream. ### Method ```javascript const stream = new ReadableStream({ start(controller) { controller.enqueue(new TextEncoder().encode('Hello')) controller.close() } }) reply.header('content-type', 'text/plain').compress(stream) ``` ``` -------------------------------- ### Per-Route Custom Brotli Options Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/api-reference-reply-compress.md Applies custom Brotli compression parameters per route for faster compression with lower quality. Requires importing the 'zlib' module. ```javascript import zlib from 'node:zlib' app.get('/fast', { compress: { brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 1 // Faster, lower compression } } } }, (request, reply) => { reply.compress({ data: 'Quick response' }) }) ``` -------------------------------- ### Compressing a Web ReadableStream Source: https://github.com/fastify/fastify-compress/blob/main/README.md The `reply.compress` method supports Web `ReadableStream`. The plugin converts the Web stream to a Node.js `Readable` before compression. ```javascript app.get('/', (req, reply) => { const stream = new ReadableStream({ start (controller) { controller.enqueue(new TextEncoder().encode('Hello from Web ReadableStream')) controller.close() } }) reply.header('content-type', 'text/plain') reply.compress(stream) }) ``` -------------------------------- ### Test No Compression with Header Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Verifies that compression is disabled when the 'x-no-compression' header is present, even if 'accept-encoding' is set. ```javascript test('no compression with x-no-compression header', async (t) => { const response = await app.inject({ url: '/', headers: { 'accept-encoding': 'gzip', 'x-no-compression': 'true' } }) t.equal(response.headers['content-encoding'], undefined) }) ``` -------------------------------- ### FastifyReply.compress() Method Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/types.md Extends the Fastify reply object with a `compress()` method to manually compress responses. This method accepts a Stream, Input, Response, or ReadableStream. ```APIDOC ## FastifyReply.compress() ### Description Adds a `compress` method to the `FastifyReply` object, allowing manual compression of response bodies. ### Method Signature `compress(input: Stream | Input | Response | ReadableStream): void` ### Parameters - **input** (Stream | Input | Response | ReadableStream) - The data to be compressed and sent as the response. ``` -------------------------------- ### Plugin Configuration: No Supported Encodings Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/errors.md This error arises when the 'encodings' option contains only unsupported or invalid values. Specify only valid encodings for compression to be possible. ```javascript if (globalCompressParams.encodings.length < 1) { next(new Error('None of the passed `encodings` were supported — compression not possible.')) return } ``` ```javascript // ❌ WRONG - 'invalid' is not a supported encoding await app.register(compress, { encodings: ['invalid'] }) ``` ```javascript // ✅ CORRECT await app.register(compress, { encodings: ['zstd', 'br', 'gzip', 'deflate'] }) ``` -------------------------------- ### Per-Route Compression Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/api-reference-plugin.md Disable global compression hooks but enable per-route compression using the 'compress' option in route configuration. This allows fine-grained control over which routes are compressed. ```javascript await app.register(compress, { global: false }) app.get('/api/data', { compress: { threshold: 512 } }, (request, reply) => { reply.send(largeDataset) }) ``` -------------------------------- ### FastifyCompressOptions Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/types.md The main configuration object for the Fastify Compress plugin, allowing customization of compression and decompression behavior, including Brotli and zlib options. ```APIDOC ## FastifyCompressOptions **Type**: Interface ### Description Main configuration object for the compress plugin. ### Properties #### Global Configuration - **`global`** (boolean) - Optional - Default: `true` - Enable global compression/decompression on all routes - **`globalCompression`** (boolean) - Optional - Default: `true` - Enable automatic response compression - **`globalDecompression`** (boolean) - Optional - Default: `true` - Enable automatic request decompression #### Response Compression - **`threshold`** (number) - Optional - Default: `1024` - Minimum payload size in bytes to compress - **`customTypes`** (RegExp | CompressibleContentTypeFunction) - Optional - Default: `default pattern` - Custom content-type detection for compression - **`encodings`** (EncodingToken[]) - Optional - Default: `all supported` - Preferred encoding order for responses - **`inflateIfDeflated`** (boolean) - Optional - Default: `false` - Auto-decompress pre-compressed bodies for incompatible clients - **`removeContentLengthHeader`** (boolean) - Optional - Default: `true` - Remove Content-Length header on compressed responses #### Request Decompression - **`requestEncodings`** (EncodingToken[]) - Optional - Default: `all supported` - Allowed encodings for request decompression - **`forceRequestEncoding`** (EncodingToken) - Optional - Default: `undefined` - Force specific decompression algorithm, ignore header #### Callbacks - **`onUnsupportedEncoding`** (function) - Optional - Custom handler for unsupported response encoding requests - **`onUnsupportedRequestEncoding`** (function) - Optional - Custom handler for unsupported request encoding - **`onInvalidRequestPayload`** (function) - Optional - Custom handler for malformed compressed request bodies #### Native Compression Options - **`brotliOptions`** (BrotliOptions) - Optional - Parameters for Node.js brotli compression - **`zlibOptions`** (ZlibOptions) - Optional - Parameters for Node.js gzip/deflate compression - **`zlib`** (unknown) - Optional - Override zlib module (for custom implementations) ### Usage ```javascript await app.register(compress, { // Global settings global: true, globalCompression: true, globalDecompression: true, // Compression threshold: 1024, encodings: ['zstd', 'br', 'gzip'], customTypes: /x-protobuf$/, removeContentLengthHeader: true, // Decompression requestEncodings: ['gzip', 'deflate'], // Options brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 4 } }, zlibOptions: { level: 6 } }) ``` ``` -------------------------------- ### Fast Brotli Compression Configuration Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/configuration.md Configure Brotli for fast compression with a lower ratio, suitable for real-time APIs. ```javascript brotliOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 1 } } ``` -------------------------------- ### Configure Compression Threshold Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/api-reference-plugin.md Register the Fastify Compress plugin with a custom compression threshold. Responses smaller than this threshold will not be compressed. ```javascript await app.register(compress, { threshold: 2048 }) ``` -------------------------------- ### Configure Only Gzip Support Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/00-START-HERE.md Register the compress plugin to only support 'gzip' encoding, ensuring compatibility with a wider range of clients. ```javascript await app.register(compress, { encodings: ['gzip'] }) ``` -------------------------------- ### Route with Pre-Compressed Inflation Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Enable automatic decompression of pre-compressed payloads (e.g., .gz files) if the client does not support compression. This ensures content is delivered correctly even when compression is not feasible. ```javascript app.get('/file', { compress: { inflateIfDeflated: true } }, (req, reply) => { // If file is .gz but client doesn't support compression, // it will be automatically decompressed reply.compress(fs.createReadStream('./archive.tar.gz')) }) ``` -------------------------------- ### Route with Custom Compression Level Source: https://github.com/fastify/fastify-compress/blob/main/_autodocs/usage-patterns.md Apply a specific zlib compression level to a route. Use level 9 for maximum compression or level 1 for faster compression. ```javascript import zlib from 'node:zlib' app.get('/reports', { compress: { zlibOptions: { level: 9 } // Maximum compression } }, (req, reply) => { reply.compress(generateHeavyReport()) }) app.get('/realtime', { compress: { zlibOptions: { level: 1 } // Fast compression } }, (req, reply) => { reply.compress(getRealtimeData()) }) ```