API & Implementation Guide

Implement HTTP compression in your applications with practical code examples

Node.js Implementation

Express.js with Compression

const express = require('express');
const compression = require('compression');

const app = express();

// Enable compression for all routes
app.use(compression({
    level: 6, // Compression level (0-9)
    threshold: 1024, // Only compress files larger than 1KB
    filter: (req, res) => {
        // Don't compress responses with this header
        if (req.headers['x-no-compression']) {
            return false;
        }
        // Use default filter function
        return compression.filter(req, res);
    }
}));

// Brotli support with shrink-ray-current
const shrinkRay = require('shrink-ray-current');
app.use(shrinkRay({
    brotli: { quality: 4 },
    zlib: { level: 6 }
}));

Native Node.js Compression

const zlib = require('zlib');
const http = require('http');
const fs = require('fs');

http.createServer((req, res) => {
    const acceptEncoding = req.headers['accept-encoding'] || '';
    const filePath = 'index.html';
    
    // Check which compression is supported
    if (/\bbr\b/.test(acceptEncoding)) {
        res.writeHead(200, { 'Content-Encoding': 'br' });
        fs.createReadStream(filePath).pipe(zlib.createBrotliCompress()).pipe(res);
    } else if (/\bgzip\b/.test(acceptEncoding)) {
        res.writeHead(200, { 'Content-Encoding': 'gzip' });
        fs.createReadStream(filePath).pipe(zlib.createGzip()).pipe(res);
    } else if (/\bdeflate\b/.test(acceptEncoding)) {
        res.writeHead(200, { 'Content-Encoding': 'deflate' });
        fs.createReadStream(filePath).pipe(zlib.createDeflate()).pipe(res);
    } else {
        res.writeHead(200, {});
        fs.createReadStream(filePath).pipe(res);
    }
}).listen(3000);

Python Implementation

Flask with Compression

from flask import Flask, Response
from flask_compress import Compress
import gzip
import brotli

app = Flask(__name__)

# Enable compression with Flask-Compress
Compress(app)
app.config['COMPRESS_LEVEL'] = 6
app.config['COMPRESS_MIN_SIZE'] = 1024

# Manual compression example
@app.route('/api/data')
def get_data():
    data = '{"large": "json data here"}'
    accept_encoding = request.headers.get('Accept-Encoding', '')
    
    if 'br' in accept_encoding:
        compressed = brotli.compress(data.encode())
        return Response(compressed, 
                       headers={'Content-Encoding': 'br',
                               'Content-Type': 'application/json'})
    elif 'gzip' in accept_encoding:
        compressed = gzip.compress(data.encode())
        return Response(compressed,
                       headers={'Content-Encoding': 'gzip',
                               'Content-Type': 'application/json'})
    
    return Response(data, content_type='application/json')

Django Middleware

# settings.py
MIDDLEWARE = [
    'django.middleware.gzip.GZipMiddleware',  # Add this
    # ... other middleware
]

# Custom compression middleware
class BrotliMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        
        if 'br' in request.META.get('HTTP_ACCEPT_ENCODING', ''):
            if len(response.content) > 1024:  # Only compress if > 1KB
                response.content = brotli.compress(response.content)
                response['Content-Encoding'] = 'br'
                response['Content-Length'] = len(response.content)
        
        return response

Java Implementation

Spring Boot Configuration

// application.properties
server.compression.enabled=true
server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
server.compression.min-response-size=1024

// Custom compression filter
@Component
public class CompressionFilter extends OncePerRequestFilter {
    
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                  HttpServletResponse response,
                                  FilterChain filterChain) throws ServletException, IOException {
        
        String acceptEncoding = request.getHeader("Accept-Encoding");
        
        if (acceptEncoding != null && acceptEncoding.contains("gzip")) {
            GzipResponseWrapper gzipResponse = new GzipResponseWrapper(response);
            filterChain.doFilter(request, gzipResponse);
            gzipResponse.close();
        } else {
            filterChain.doFilter(request, response);
        }
    }
}

PHP Implementation

PHP Compression

<?php
// Enable output compression
if (!ob_start("ob_gzhandler")) {
    ob_start();
}

// Manual compression based on Accept-Encoding
function compressOutput($data) {
    $acceptEncoding = $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '';
    
    if (strpos($acceptEncoding, 'br') !== false && function_exists('brotli_compress')) {
        header('Content-Encoding: br');
        return brotli_compress($data, 4);
    } elseif (strpos($acceptEncoding, 'gzip') !== false) {
        header('Content-Encoding: gzip');
        return gzencode($data, 6);
    } elseif (strpos($acceptEncoding, 'deflate') !== false) {
        header('Content-Encoding: deflate');
        return gzdeflate($data, 6);
    }
    
    return $data;
}

// Usage
$jsonData = json_encode(['large' => 'data structure']);
echo compressOutput($jsonData);

Go Implementation

Go HTTP Server with Compression

package main

import (
    "compress/gzip"
    "io"
    "net/http"
    "strings"
    
    "github.com/andybalholm/brotli"
)

type compressResponseWriter struct {
    io.Writer
    http.ResponseWriter
}

func (w compressResponseWriter) Write(b []byte) (int, error) {
    return w.Writer.Write(b)
}

func compressionMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        acceptEncoding := r.Header.Get("Accept-Encoding")
        
        if strings.Contains(acceptEncoding, "br") {
            w.Header().Set("Content-Encoding", "br")
            br := brotli.NewWriterLevel(w, brotli.DefaultCompression)
            defer br.Close()
            w = compressResponseWriter{Writer: br, ResponseWriter: w}
        } else if strings.Contains(acceptEncoding, "gzip") {
            w.Header().Set("Content-Encoding", "gzip")
            gz := gzip.NewWriter(w)
            defer gz.Close()
            w = compressResponseWriter{Writer: gz, ResponseWriter: w}
        }
        
        next.ServeHTTP(w, r)
    })
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", handler)
    
    http.ListenAndServe(":8080", compressionMiddleware(mux))
}

Client-Side Implementation

JavaScript Fetch with Compression

// Modern browsers automatically handle decompression
fetch('/api/data', {
    headers: {
        'Accept-Encoding': 'gzip, deflate, br'
    }
})
.then(response => {
    // Response is automatically decompressed
    console.log('Content-Encoding:', response.headers.get('Content-Encoding'));
    return response.json();
})
.then(data => console.log(data));

// Node.js client with compression
const https = require('https');
const zlib = require('zlib');

const options = {
    hostname: 'api.example.com',
    path: '/data',
    headers: {
        'Accept-Encoding': 'gzip, deflate, br'
    }
};

https.get(options, (res) => {
    let output;
    
    switch (res.headers['content-encoding']) {
        case 'br':
            output = res.pipe(zlib.createBrotliDecompress());
            break;
        case 'gzip':
            output = res.pipe(zlib.createGunzip());
            break;
        case 'deflate':
            output = res.pipe(zlib.createInflate());
            break;
        default:
            output = res;
    }
    
    let data = '';
    output.on('data', chunk => data += chunk);
    output.on('end', () => console.log(JSON.parse(data)));
});

Testing Your Implementation

cURL Testing Commands

# Test gzip compression
curl -H "Accept-Encoding: gzip" -I https://yourapi.com/endpoint

# Test all compression methods
curl -H "Accept-Encoding: gzip, deflate, br" -v https://yourapi.com/endpoint

# Download and decompress
curl -H "Accept-Encoding: gzip" https://yourapi.com/data | gunzip

# Compare compressed vs uncompressed size
curl -s https://yourapi.com/data | wc -c
curl -H "Accept-Encoding: gzip" -s https://yourapi.com/data | wc -c

Best Practices

Implementation Guidelines

  1. Content negotiation: Always check Accept-Encoding header
  2. Vary header: Include "Vary: Accept-Encoding" in responses
  3. Minimum size: Don't compress files under 1KB
  4. Content types: Only compress text-based formats
  5. Error handling: Fallback to uncompressed on compression errors
  6. Streaming: Use streaming compression for large responses

Common Headers

HTTP Headers Reference

  • Request: Accept-Encoding: gzip, deflate, br
  • Response: Content-Encoding: gzip
  • Response: Vary: Accept-Encoding
  • Transfer: Transfer-Encoding: gzip (for chunked)