{"id":17347,"library":"request-etag","title":"ETag-based HTTP Response Caching","description":"request-etag is a small, in-memory module designed for ETag-based HTTP response caching. It manages the `If-None-Match` header automatically for subsequent GET requests to the same URL, retrieving cached bodies for 304 Not Modified responses. The package currently leverages `lru-cache` for its underlying caching mechanism, which can be configured with options like `max` size. Crucially, `request-etag` defaults to using the `request` library as its HTTP client, which has been officially deprecated and is no longer maintained since February 11th, 2020. While an alternative HTTP client can be injected, it *must* adhere to the `request` library's API signature. The package's current stable version is 2.0.3, but its reliance on a deprecated core dependency suggests a slow or inactive release cadence, limiting its suitability for new projects. Its primary differentiator is its focused, lightweight approach to abstracting ETag caching logic.","status":"deprecated","version":"2.0.3","language":"javascript","source_language":"en","source_url":"https://github.com/Belema/request-etag","tags":["javascript","request","etag","request-etag","etag-request","http","http-etag","etag-http"],"install":[{"cmd":"npm install request-etag","lang":"bash","label":"npm"},{"cmd":"yarn add request-etag","lang":"bash","label":"yarn"},{"cmd":"pnpm add request-etag","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Provides the underlying in-memory caching mechanism for storing HTTP responses.","package":"lru-cache","optional":false},{"reason":"Serves as the default HTTP client for making requests. This library is officially deprecated and unmaintained, posing security and stability risks.","package":"request","optional":true}],"imports":[{"note":"The package uses CommonJS `require` syntax for its default export. Direct ESM `import` is not supported without a CommonJS wrapper or bundler configuration due to its age.","wrong":"import ETagRequest from 'request-etag';","symbol":"ETagRequest","correct":"const ETagRequest = require('request-etag');"},{"note":"The default HTTP client is the deprecated `request` library. It is strongly recommended to provide an alternative, modern, and maintained HTTP client (wrapped to match `request`'s API signature) as the second argument to the constructor.","wrong":"const eTagRequest = new ETagRequest(cacheConfig);","symbol":"ETagRequest constructor","correct":"const eTagRequest = new ETagRequest(cacheConfig, modernHttpClient);"},{"note":"The callback function adheres to the `(error, response, body)` signature, mimicking the `request` library's callback pattern for consistent handling of HTTP responses.","symbol":"Callback signature","correct":"eTagRequest(url, function (error, response, body) { /* ... */ });"}],"quickstart":{"code":"const ETagRequest = require('request-etag');\nconst request = require('request'); // In a real application, use a modern HTTP client compatible with 'request' API\n\n// Configure the cache, e.g., max 10MB to store response bodies\nconst cacheConfig = {\n    max: 10 * 1024 * 1024 // 10MB limit for the cache\n};\n\n// Initialize ETagRequest. In a production environment, 'request' should be replaced \n// with a modern, maintained HTTP client that provides the same API signature.\nconst eTagRequest = new ETagRequest(cacheConfig, request);\n\n// Define a target URL for caching\nconst urlToCache = 'https://www.google.com/'; \n\nconsole.log('--- First request (expecting 200 OK) ---');\neTagRequest(urlToCache, function (error, response, body) {\n    if (error) {\n        console.error('Initial request failed:', error);\n        return;\n    }\n\n    if (response.statusCode === 200) {\n        console.log(`Status: ${response.statusCode} - Body retrieved from actual HTTP response.`);\n        // console.log(body.substring(0, 100) + '...'); // Log a snippet of the body\n    } else {\n        console.log(`Initial request unexpected status: ${response.statusCode}`);\n    }\n\n    console.log('\\n--- Second request (expecting 304 Not Modified from cache) ---');\n    eTagRequest(urlToCache, function (error2, response2, body2) {\n        if (error2) {\n            console.error('Second request failed:', error2);\n            return;\n        }\n\n        if (response2.statusCode === 304) {\n            console.log(`Status: ${response2.statusCode} - Body retrieved from internal cache.`);\n            // console.log(body2.substring(0, 100) + '...'); // Log a snippet of the cached body\n        } else if (response2.statusCode === 200) {\n            console.log(`Status: ${response2.statusCode} - Unexpected 200 on second request, cache might be bypassed.`);\n        } else {\n            console.log(`Second request unexpected status: ${response2.statusCode}`);\n        }\n    });\n});","lang":"javascript","description":"This quickstart demonstrates how to initialize `request-etag` with a cache configuration and perform ETag-aware GET requests, showing the behavior of both initial 200 OK and subsequent 304 Not Modified responses with cached bodies."},"warnings":[{"fix":"Do not use `request-etag` in new projects. For existing projects, it is imperative to provide an alternative, maintained HTTP client (e.g., `axios`, `node-fetch`, or `undici` wrapped to match `request`'s API) to the `ETagRequest` constructor. Consider migrating to a more modern and actively maintained caching solution.","message":"Critical security vulnerability and maintenance risk due to reliance on the deprecated 'request' library. The 'request' package is no longer maintained, meaning it won't receive security updates or bug fixes.","severity":"breaking","affected_versions":">=0.0.1"},{"fix":"Ensure all requests intended for caching are GET requests. For other methods, `request-etag` will not provide caching benefits.","message":"The module is explicitly designed for GET requests only; other HTTP methods (POST, PUT, DELETE, etc.) will not be cached.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"Verify that your server is configured to send `ETag` headers for cacheable resources. Avoid sending `Cookie` headers with requests if you intend `request-etag` to cache their responses.","message":"Caching will not occur if the HTTP response lacks an ETag header, or if the request includes a non-empty `Cookie` header.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"When overriding the default client, ensure your custom client function accepts `(url, callback)` or `(options, callback)` and specifically uses the `(error, response, body)` callback signature, as expected by `request-etag`.","message":"The underlying HTTP client provided to `ETagRequest` must strictly adhere to the API signature of the deprecated `request` library.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"Adjust the `max` configuration option in `cacheConfig` to accommodate the maximum expected size of the response bodies you wish to cache. If bodies exceed this, they will be fetched every time.","message":"Responses with bodies larger than the configured `max` cache size (set in `cacheConfig`) will not be stored in the cache.","severity":"gotcha","affected_versions":">=0.0.1"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure that the HTTP request you are attempting to cache is a GET request.","cause":"The HTTP method used for the request was not GET. `request-etag` only caches GET requests.","error":"My request is not being cached, even though I expect it to be."},{"fix":"Check the server's configuration to confirm that `ETag` headers are being sent for the resources you wish to cache.","cause":"The server response did not include an ETag header, which is essential for `request-etag` to identify and manage cached resources.","error":"My request is not being cached, even though I expect it to be."},{"fix":"Remove any `Cookie` headers from requests that you intend for `request-etag` to cache. If cookies are necessary, `request-etag` cannot cache that specific response.","cause":"The outbound request included a non-empty `Cookie` header, which `request-etag` interprets as a reason not to cache the response.","error":"My request is not being cached, even though I expect it to be."},{"fix":"Verify that your custom HTTP client's function signature and callback arguments (specifically `(error, response, body)`) perfectly mimic those of the `request` library, as `request-etag` relies on this specific interface.","cause":"The custom HTTP client provided to the `ETagRequest` constructor does not precisely match the expected API signature of the deprecated `request` library.","error":"TypeError: Cannot read properties of undefined (reading 'call') or similar when using a custom HTTP client."}],"ecosystem":"npm","meta_description":null}