HTTP cache semantics library implementing RFC 7234/9111 rules for proper caching behavior
npx @tessl/cli install tessl/npm-http-cache-semantics@4.2.00
# HTTP Cache Semantics
1
2
HTTP Cache Semantics is a JavaScript library that implements HTTP caching rules according to RFC 7234/9111 specifications. It provides the `CachePolicy` class that determines when HTTP responses can be reused from cache, handles cache validation, and manages complex caching scenarios including `Vary` headers, proxy revalidation, and authenticated responses.
3
4
## Package Information
5
6
- **Package Name**: http-cache-semantics
7
- **Package Type**: npm
8
- **Language**: JavaScript (CommonJS)
9
- **Installation**: `npm install http-cache-semantics`
10
11
## Core Imports
12
13
```javascript
14
const CachePolicy = require("http-cache-semantics");
15
```
16
17
For ES modules:
18
19
```javascript
20
import CachePolicy from "http-cache-semantics";
21
```
22
23
## Basic Usage
24
25
```javascript
26
const CachePolicy = require("http-cache-semantics");
27
28
// Create policy from request and response
29
const policy = new CachePolicy(
30
{
31
url: "/api/users",
32
method: "GET",
33
headers: { "accept": "application/json" }
34
},
35
{
36
status: 200,
37
headers: { "cache-control": "public, max-age=3600" }
38
}
39
);
40
41
// Check if response can be stored
42
if (policy.storable()) {
43
// Store in cache with TTL
44
cache.set(request.url, {
45
policy: policy,
46
body: response.body
47
}, policy.timeToLive());
48
}
49
50
// Later, check if cached response satisfies new request
51
const newRequest = { url: "/api/users", headers: {} };
52
if (policy.satisfiesWithoutRevalidation(newRequest)) {
53
// Use cached response with updated headers
54
return {
55
headers: policy.responseHeaders(),
56
body: cachedBody
57
};
58
}
59
```
60
61
## Capabilities
62
63
### CachePolicy Constructor
64
65
Creates a new cache policy instance that tracks cacheability and freshness of HTTP responses.
66
67
```javascript { .api }
68
/**
69
* Creates a new CachePolicy instance
70
* @param {HttpRequest} req - Incoming client request
71
* @param {HttpResponse} res - Received server response
72
* @param {Object} [options={}] - Configuration options
73
* @param {boolean} [options.shared=true] - Is cache shared (public proxy) vs private
74
* @param {number} [options.cacheHeuristic=0.1] - Fallback heuristic fraction for cache duration
75
* @param {number} [options.immutableMinTimeToLive=86400000] - Minimum TTL for immutable responses in ms
76
* @param {boolean} [options.ignoreCargoCult=false] - Override nonsense cache headers
77
*/
78
constructor(req, res, options = {})
79
```
80
81
### Cache Storage Methods
82
83
Methods for determining if a response can be stored and used from cache.
84
85
```javascript { .api }
86
/**
87
* Returns true if the response can be stored in cache
88
* @returns {boolean} false if response must not be cached
89
*/
90
storable()
91
92
/**
93
* Checks if cached response satisfies new request without revalidation
94
* @param {HttpRequest} req - New incoming HTTP request
95
* @returns {boolean} true if cached response can be used directly
96
*/
97
satisfiesWithoutRevalidation(req)
98
```
99
100
### Advanced Request Evaluation
101
102
Comprehensive method for determining cache usage with support for stale-while-revalidate.
103
104
```javascript { .api }
105
/**
106
* Evaluates how cached entry can satisfy new request
107
* @param {HttpRequest} req - New incoming HTTP request
108
* @returns {EvaluationResult} Object with revalidation and response info
109
*/
110
evaluateRequest(req)
111
```
112
113
### Response Headers Management
114
115
Method for getting properly updated headers when serving cached responses.
116
117
```javascript { .api }
118
/**
119
* Returns updated response headers for serving cached response
120
* Removes hop-by-hop headers and updates Age/Date
121
* @returns {Record<string, string>} Updated headers object for client response
122
*/
123
responseHeaders()
124
```
125
126
### Time and Freshness Methods
127
128
Methods for determining cache entry age, freshness, and time-to-live.
129
130
```javascript { .api }
131
/**
132
* Returns current age of cached response in seconds
133
* @returns {number} Age in seconds including resident time
134
*/
135
age()
136
137
/**
138
* Returns maximum age (freshness lifetime) in seconds
139
* @returns {number} Max-age value in seconds
140
*/
141
maxAge()
142
143
/**
144
* Returns remaining time cache entry may be useful in milliseconds
145
* @returns {number} Time-to-live in milliseconds
146
*/
147
timeToLive()
148
149
/**
150
* Returns true if response is past its expiration date
151
* @returns {boolean} true if stale (may still be usable in some cases)
152
*/
153
stale()
154
155
/**
156
* Returns Date header timestamp or response time if invalid
157
* @returns {number} Timestamp in milliseconds
158
*/
159
date()
160
```
161
162
### Stale Response Handling
163
164
Methods for working with stale responses using RFC 5861 extensions.
165
166
```javascript { .api }
167
/**
168
* Returns true if stale-while-revalidate is currently allowed
169
* @returns {boolean} true if stale response can be used while revalidating
170
*/
171
useStaleWhileRevalidate()
172
```
173
174
### Cache Revalidation
175
176
Methods for efficiently updating stale cache entries by revalidating with origin server.
177
178
```javascript { .api }
179
/**
180
* Returns headers for revalidation request to origin server
181
* Allows server to return 304 Not Modified to save bandwidth
182
* @param {HttpRequest} incomingReq - New incoming HTTP request
183
* @returns {Record<string, string>} Headers object for revalidation request
184
*/
185
revalidationHeaders(incomingReq)
186
187
/**
188
* Creates updated policy from revalidation response
189
* @param {HttpRequest} request - Latest HTTP request for cached entry
190
* @param {HttpResponse} response - Revalidation response from origin server
191
* @returns {RevalidationResult} Object with updated policy and modification status
192
*/
193
revalidatedPolicy(request, response)
194
```
195
196
### Serialization Methods
197
198
Methods for storing and restoring cache policy objects.
199
200
```javascript { .api }
201
/**
202
* Serializes CachePolicy instance to JSON-serializable object
203
* @returns {Object} Serialized object for storage
204
*/
205
toObject()
206
207
/**
208
* Creates CachePolicy instance from serialized object
209
* @param {Object} obj - Previously serialized CachePolicy object
210
* @returns {CachePolicy} Restored CachePolicy instance
211
*/
212
static fromObject(obj)
213
```
214
215
### Utility Methods
216
217
```javascript { .api }
218
/**
219
* Returns current time in milliseconds (can be monkey-patched for testing)
220
* @returns {number} Current timestamp
221
*/
222
now()
223
```
224
225
## Types
226
227
```javascript { .api }
228
/**
229
* HTTP request object
230
* @typedef {Object} HttpRequest
231
* @property {Record<string, string>} headers - Request headers (lowercase names)
232
* @property {string} [method="GET"] - HTTP method
233
* @property {string} [url] - Request URL
234
*/
235
236
/**
237
* HTTP response object
238
* @typedef {Object} HttpResponse
239
* @property {Record<string, string>} headers - Response headers (lowercase names)
240
* @property {number} [status=200] - HTTP status code
241
*/
242
243
/**
244
* Result from evaluateRequest method
245
* @typedef {Object} EvaluationResult
246
* @property {Object} [response] - Cached response can be used
247
* @property {Record<string, string>} [response.headers] - Updated headers for cached response
248
* @property {Object} [revalidation] - Revalidation needed
249
* @property {Record<string, string>} [revalidation.headers] - Headers for revalidation request
250
* @property {boolean} [revalidation.synchronous] - Whether to wait for revalidation
251
*/
252
253
/**
254
* Result from revalidatedPolicy method
255
* @typedef {Object} RevalidationResult
256
* @property {CachePolicy} policy - Updated CachePolicy instance
257
* @property {boolean} modified - Whether response body changed
258
* @property {boolean} matches - Whether revalidation response matches
259
*/
260
```
261
262
## Complete Usage Example
263
264
```javascript
265
const CachePolicy = require("http-cache-semantics");
266
267
// Cache storage implementation
268
const cache = new Map();
269
270
async function handleRequest(incomingRequest) {
271
// Try to get from cache
272
const cached = cache.get(incomingRequest.url);
273
274
if (!cached) {
275
// Cache miss - fetch from origin
276
const originResponse = await fetch(incomingRequest);
277
const policy = new CachePolicy(incomingRequest, originResponse);
278
279
if (policy.storable()) {
280
cache.set(incomingRequest.url, {
281
policy: policy,
282
body: originResponse.body
283
});
284
}
285
286
return {
287
headers: policy.responseHeaders(),
288
body: originResponse.body
289
};
290
}
291
292
// Evaluate cached entry
293
const { revalidation, response } = cached.policy.evaluateRequest(incomingRequest);
294
295
if (revalidation) {
296
// Need to revalidate with origin
297
const revalidationRequest = {
298
...incomingRequest,
299
headers: revalidation.headers
300
};
301
302
const revalidationResponse = await fetch(revalidationRequest);
303
const { policy: newPolicy, modified } = cached.policy.revalidatedPolicy(
304
incomingRequest,
305
revalidationResponse
306
);
307
308
const body = modified ? revalidationResponse.body : cached.body;
309
310
if (newPolicy.storable()) {
311
cache.set(incomingRequest.url, {
312
policy: newPolicy,
313
body: body
314
});
315
}
316
317
if (revalidation.synchronous) {
318
// Must wait for revalidation
319
return {
320
headers: newPolicy.responseHeaders(),
321
body: body
322
};
323
}
324
}
325
326
// Use cached response
327
return {
328
headers: response.headers,
329
body: cached.body
330
};
331
}
332
```