zuplo 7.0.0 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/docs/articles/ci-cd-azure/basic-deployment.mdx +2 -2
  2. package/docs/articles/ci-cd-azure/deploy-and-test.mdx +1 -1
  3. package/docs/articles/ci-cd-azure/local-testing.mdx +2 -2
  4. package/docs/articles/ci-cd-azure/multi-stage-deployment.mdx +3 -3
  5. package/docs/articles/ci-cd-azure/pr-preview-environments.mdx +1 -1
  6. package/docs/articles/ci-cd-azure/tag-based-releases.mdx +1 -1
  7. package/docs/articles/ci-cd-bitbucket/basic-deployment.mdx +1 -1
  8. package/docs/articles/ci-cd-bitbucket/deploy-and-test.mdx +1 -1
  9. package/docs/articles/ci-cd-bitbucket/local-testing.mdx +1 -1
  10. package/docs/articles/ci-cd-bitbucket/multi-stage-deployment.mdx +1 -1
  11. package/docs/articles/ci-cd-bitbucket/pr-preview-environments.mdx +1 -1
  12. package/docs/articles/ci-cd-bitbucket/tag-based-releases.mdx +1 -1
  13. package/docs/articles/ci-cd-circleci/basic-deployment.mdx +1 -1
  14. package/docs/articles/ci-cd-circleci/deploy-and-test.mdx +1 -1
  15. package/docs/articles/ci-cd-circleci/local-testing.mdx +2 -2
  16. package/docs/articles/ci-cd-circleci/multi-stage-deployment.mdx +3 -3
  17. package/docs/articles/ci-cd-circleci/pr-preview-environments.mdx +1 -1
  18. package/docs/articles/ci-cd-circleci/tag-based-releases.mdx +1 -1
  19. package/docs/articles/ci-cd-github/basic-deployment.mdx +1 -1
  20. package/docs/articles/ci-cd-github/cleanup-on-branch-delete.mdx +2 -2
  21. package/docs/articles/ci-cd-github/deploy-and-test.mdx +1 -1
  22. package/docs/articles/ci-cd-github/local-testing.mdx +2 -2
  23. package/docs/articles/ci-cd-github/multi-stage-deployment.mdx +3 -3
  24. package/docs/articles/ci-cd-github/pr-preview-environments.mdx +2 -2
  25. package/docs/articles/ci-cd-github/tag-based-releases.mdx +1 -1
  26. package/docs/articles/ci-cd-gitlab/basic-deployment.mdx +1 -1
  27. package/docs/articles/ci-cd-gitlab/deploy-and-test.mdx +1 -1
  28. package/docs/articles/ci-cd-gitlab/local-testing.mdx +1 -1
  29. package/docs/articles/ci-cd-gitlab/mr-preview-environments.mdx +1 -1
  30. package/docs/articles/ci-cd-gitlab/multi-stage-deployment.mdx +1 -1
  31. package/docs/articles/ci-cd-gitlab/tag-based-releases.mdx +1 -1
  32. package/docs/articles/github-deployment-testing.mdx +1 -1
  33. package/docs/articles/graphql-caching.mdx +2 -0
  34. package/docs/articles/local-development.mdx +4 -4
  35. package/docs/articles/monorepo-deployment.mdx +3 -3
  36. package/docs/articles/sharing-code-across-projects.mdx +2 -2
  37. package/docs/articles/step-1-setup-basic-gateway-local.mdx +1 -1
  38. package/docs/articles/testing.mdx +5 -5
  39. package/docs/articles/troubleshooting-slow-responses.mdx +5 -0
  40. package/docs/articles/update-zup-in-github-action.mdx +1 -1
  41. package/docs/caching/cdn-caching.mdx +397 -0
  42. package/docs/caching/custom-caching-policy.mdx +426 -0
  43. package/docs/caching/dynamic-cache-rules.mdx +427 -0
  44. package/docs/caching/gateway-caching.mdx +308 -0
  45. package/docs/caching/overview.mdx +150 -0
  46. package/docs/caching/partial-response-caching.mdx +641 -0
  47. package/docs/cli/overview.mdx +2 -3
  48. package/docs/dedicated/akamai/caching.mdx +245 -140
  49. package/docs/dev-portal/local-development.mdx +1 -1
  50. package/docs/dev-portal/migration.mdx +1 -1
  51. package/docs/mcp-gateway/quickstart-local.mdx +1 -1
  52. package/docs/policies/api-key-inbound/schema.json +4 -2
  53. package/docs/programmable-api/cache.mdx +7 -0
  54. package/docs/programmable-api/memory-zone-read-through-cache.mdx +2 -0
  55. package/docs/programmable-api/streaming-zone-cache.mdx +2 -0
  56. package/docs/programmable-api/zone-cache.mdx +7 -0
  57. package/package.json +5 -5
@@ -2,22 +2,23 @@
2
2
  title: Controlling Akamai CDN Caching
3
3
  sidebar_label: CDN Caching
4
4
  description:
5
- How to control Akamai CDN caching behavior using response headers from your
6
- Zuplo API Gateway.
5
+ Cache Zuplo responses at the Akamai edge with the CDN Cache Control policy.
6
+ Covers Edge-Control TTLs, Edge-Cache-Tag purge tags, and the Property Manager
7
+ settings that make them work.
7
8
  ---
8
9
 
9
- <!-- vale Vale.Spelling = NO -->
10
+ An Akamai property in front of a Zuplo gateway can absorb most of the read
11
+ traffic an API serves. A catalog endpoint that returns the same payload to every
12
+ caller doesn't need to reach the gateway 40,000 times an hour. It needs to reach
13
+ it once every 30 minutes, and again the moment the catalog changes.
10
14
 
11
- When running Zuplo on Akamai Connected Cloud, your API Gateway can control how
12
- the Akamai CDN caches responses by setting the `Cache-Control` header. This
13
- allows you to optimize caching behavior for different endpoints without
14
- modifying Akamai Property Manager configurations.
15
+ The CDN Cache Control policy writes the headers Akamai reads to make that
16
+ happen: `Edge-Control` for the edge TTL, and `Edge-Cache-Tag` for the purge tags
17
+ that let a content update invalidate the edge in seconds instead of waiting out
18
+ the TTL.
15
19
 
16
20
  ## How Akamai caching works
17
21
 
18
- Akamai's CDN can cache responses at edge servers to reduce load to your Zuplo
19
- API Gateway and improve response times for clients.
20
-
21
22
  <Diagram type="sequence" height="h-[420px]">
22
23
  <DiagramActor id="client" variant="yellow">
23
24
  Client
@@ -28,185 +29,289 @@ API Gateway and improve response times for clients.
28
29
  <DiagramActor id="gateway" variant="zuplo">
29
30
  Zuplo
30
31
  </DiagramActor>
31
- <DiagramActor id="backend" variant="green">
32
- Backend
33
- </DiagramActor>
34
32
  <DiagramMessage from="client" to="cdn">
35
33
  Request (cache miss)
36
34
  </DiagramMessage>
37
35
  <DiagramMessage from="cdn" to="gateway">
38
- Forward request
39
- </DiagramMessage>
40
- <DiagramMessage from="gateway" to="backend">
41
- Forward request
42
- </DiagramMessage>
43
- <DiagramMessage from="backend" to="gateway">
44
- Response
36
+ Forward to origin
45
37
  </DiagramMessage>
46
38
  <DiagramMessage from="gateway" to="cdn">
47
- Response + Cache-Control headers
39
+ Response + Edge-Control + tag
48
40
  </DiagramMessage>
49
41
  <DiagramMessage from="cdn" to="client">
50
- Response (cached at edge)
42
+ Response + Cache-Control (client TTL)
51
43
  </DiagramMessage>
52
44
  </Diagram>
53
45
 
54
- When a request arrives, Akamai checks if a cached response exists. On a cache
55
- miss, the request goes to Zuplo, which can set cache headers on the response.
56
- Akamai caches the response according to those headers and serves subsequent
57
- requests directly from the edge cache.
58
-
59
- The CDN determines caching behavior based on:
46
+ What the edge does depends on the property configuration and on the headers
47
+ Zuplo sends:
60
48
 
61
- 1. **Akamai Property Manager settings** - Default caching rules configured in
62
- your CDN property
63
- 2. **Origin response headers** - Headers sent by Zuplo that can override or
64
- influence default behavior
49
+ 1. **Akamai Property Manager settings.** The default caching rules configured in
50
+ your CDN property.
51
+ 2. **Origin response headers.** What Zuplo sends, which can override or
52
+ influence those defaults once the property is configured to honor them.
65
53
 
66
- When your Akamai property is configured to "Honor origin Cache-Control and
67
- Expires" headers, Zuplo can control caching behavior on a per-response basis.
54
+ The edge TTL and the purge tags travel in headers the client never acts on, so
55
+ the response the client receives carries only `Cache-Control`. Akamai also
56
+ strips `Edge-Cache-Tag` before responses leave the edge unless the Cache Tag
57
+ Visibility behavior is enabled, so tags stay internal by default.
68
58
 
69
59
  For complete details on Akamai's caching behavior, see the
70
60
  [Akamai caching documentation](https://techdocs.akamai.com/property-mgr/docs/caching-2).
71
61
 
72
- ## Cache-Control header
62
+ ## Set the edge TTL and purge tags
73
63
 
74
- The `Cache-Control` header controls caching for both the CDN and downstream
75
- clients (browsers). Akamai honors the following directives when configured to
76
- respect origin headers:
64
+ Add the CDN Cache Control policy to the outbound pipeline of any route whose
65
+ responses are safe for a shared cache to replay. Set `cdn` to `akamai` and the
66
+ policy renders everything else into Akamai's dialect.
77
67
 
78
- | Directive | Description |
79
- | ----------------- | ----------------------------------------------------------- |
80
- | `max-age` | Cache duration for browsers and downstream caches (seconds) |
81
- | `s-maxage` | Cache duration for shared caches like CDNs (seconds) |
82
- | `no-cache` | Revalidate with origin before serving cached content |
83
- | `no-store` | Don't cache the response at all |
84
- | `private` | Only allow browser caching, not CDN caching |
85
- | `public` | Allow caching by CDNs and browsers |
86
- | `must-revalidate` | Must revalidate after max-age expires |
87
-
88
- ### Using s-maxage for CDN caching
68
+ ```json title="config/policies.json"
69
+ {
70
+ "name": "catalog-edge-cache",
71
+ "policyType": "cdn-cache-control-outbound",
72
+ "handler": {
73
+ "export": "CdnCacheControlOutboundPolicy",
74
+ "module": "$import(@zuplo/runtime)",
75
+ "options": {
76
+ "cdn": "akamai",
77
+ "edge": {
78
+ "maxAge": 1800
79
+ },
80
+ "client": {
81
+ "visibility": "public",
82
+ "maxAge": 60
83
+ },
84
+ "tags": ["catalog", "cities"]
85
+ }
86
+ }
87
+ }
88
+ ```
89
89
 
90
- The `s-maxage` directive is specifically for shared caches like CDNs. When both
91
- `max-age` and `s-maxage` are present, Akamai uses `s-maxage` for edge caching
92
- and forwards `max-age` to browsers:
90
+ Akamai receives:
93
91
 
92
+ ```http
93
+ Cache-Control: public, max-age=60
94
+ Edge-Control: cache-maxage=30m
95
+ Edge-Cache-Tag: catalog,cities
94
96
  ```
95
- Cache-Control: public, max-age=60, s-maxage=3600
97
+
98
+ The edge holds the response for 30 minutes and absorbs the traffic. Clients
99
+ re-check every 60 seconds, so a purge of the `cities` tag reaches every caller
100
+ within a minute rather than within half an hour.
101
+
102
+ The policy also removes an `Edge-Control` header your backend set that the
103
+ policy is not writing itself, because a targeted header outranks `Cache-Control`
104
+ and an upstream value would silently beat the TTL configured here.
105
+
106
+ :::note
107
+
108
+ `respectUpstream` is on by default. An upstream `Cache-Control` of `no-store`,
109
+ `no-cache`, or `private`, or a `Set-Cookie` on the response, suppresses every
110
+ edge header and purge tag. The backend keeps the final say even when the policy
111
+ is applied broadly.
112
+
113
+ :::
114
+
115
+ Splitting the edge TTL from the client TTL is the point of the policy. Because
116
+ only Akamai reads `Edge-Control`, `Cache-Control` stays free to say whatever the
117
+ client should do, down to `private, max-age=0` for a response that requires an
118
+ `Authorization` header but is identical for every caller:
119
+
120
+ ```http
121
+ Cache-Control: private, max-age=0
122
+ Edge-Control: cache-maxage=5m
96
123
  ```
97
124
 
98
- This example caches content at the CDN for 1 hour while instructing browsers to
99
- cache for only 1 minute.
125
+ Akamai reads `Edge-Control` and ignores `Cache-Control` for its own decision, so
126
+ it never sees the `private`. The edge caches; nothing downstream does. For the
127
+ reasoning behind the split and the variations on it, see
128
+ [Cache at the CDN](../../caching/cdn-caching.mdx).
129
+
130
+ :::caution{title="Don't put the Caching policy on the same route"}
100
131
 
101
- ### Common Cache-Control patterns
132
+ Keep the [Caching](../../policies/caching-inbound.mdx) policy off any route that
133
+ uses CDN Cache Control. The Caching policy serves a hit from an inbound policy,
134
+ which short-circuits the pipeline before outbound policies run, so CDN Cache
135
+ Control never executes on a gateway cache hit. Akamai then receives the copy
136
+ that the Caching policy stored, and the Caching policy sanitizes every copy it
137
+ stores: it drops several CDN cache headers (exactly which ones depends on the
138
+ CDN) and overwrites `Cache-Control` with its own `s-maxage` (its TTL, 60 seconds
139
+ by default). The edge and client TTLs collapse into one number. Cache misses run
140
+ the full outbound stack and look correct, so the problem stays invisible until
141
+ traffic warms the cache, and nothing logs it. Pick one place to cache.
102
142
 
103
- | Scenario | Header Value |
104
- | -------------------------- | ---------------------------------------------------- |
105
- | CDN: 1 hour, Browser: none | `Cache-Control: public, s-maxage=3600, max-age=0` |
106
- | CDN: 1 day, Browser: 5 min | `Cache-Control: public, s-maxage=86400, max-age=300` |
107
- | No caching | `Cache-Control: no-store` |
108
- | Browser only, no CDN | `Cache-Control: private, max-age=3600` |
143
+ :::
109
144
 
110
- ## Setting cache headers in Zuplo
145
+ ## Akamai-specific constraints
111
146
 
112
- ### Using the Set Headers policy
147
+ ### Stale serving needs Property Manager
113
148
 
114
- The simplest way to add cache headers is using the
115
- [Set Headers Outbound Policy](../../policies/set-headers-outbound.mdx):
149
+ `edge.staleWhileRevalidate` and `edge.staleIfError` have no `Edge-Control`
150
+ equivalent. Rather than dropping those directives silently, the policy rejects
151
+ the combination on Akamai. Two ways forward:
152
+
153
+ - **Configure stale serving in Property Manager.** Leave
154
+ `edge.staleWhileRevalidate` and `edge.staleIfError` unset, keep `strategy` at
155
+ its default, and let the property decide how long the edge may serve a stale
156
+ object while revalidating or while the origin is failing.
157
+ - **Set `strategy` to `s-maxage`.** The edge TTL and the stale windows then
158
+ travel in `Cache-Control`, which works on a property that honors origin
159
+ `Cache-Control` but has not enabled `Edge-Control`.
116
160
 
117
161
  ```json title="config/policies.json"
118
162
  {
119
- "name": "cache-one-hour",
120
- "policyType": "set-headers-outbound",
163
+ "name": "catalog-edge-cache",
164
+ "policyType": "cdn-cache-control-outbound",
121
165
  "handler": {
122
- "export": "SetHeadersOutboundPolicy",
166
+ "export": "CdnCacheControlOutboundPolicy",
123
167
  "module": "$import(@zuplo/runtime)",
124
168
  "options": {
125
- "headers": [
126
- {
127
- "name": "Cache-Control",
128
- "value": "public, max-age=60, s-maxage=3600"
129
- }
130
- ]
169
+ "cdn": "akamai",
170
+ "strategy": "s-maxage",
171
+ "edge": {
172
+ "maxAge": 1800,
173
+ "staleIfError": 86400
174
+ },
175
+ "client": {
176
+ "visibility": "public",
177
+ "maxAge": 60
178
+ }
131
179
  }
132
180
  }
133
181
  }
134
182
  ```
135
183
 
136
- This configuration caches responses at the CDN for 1 hour while allowing
137
- browsers to cache for only 1 minute.
138
-
139
- ### Using custom code
140
-
141
- For dynamic cache control based on response content or status, use a custom
142
- outbound policy:
143
-
144
- ```typescript title="modules/cache-control.ts"
145
- import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
146
-
147
- export default async function (
148
- response: Response,
149
- request: ZuploRequest,
150
- context: ZuploContext,
151
- ) {
152
- const headers = new Headers(response.headers);
153
-
154
- // Cache successful responses for 1 hour at CDN, 1 minute in browser
155
- if (response.status >= 200 && response.status < 300) {
156
- headers.set("Cache-Control", "public, max-age=60, s-maxage=3600");
157
- }
158
- // Don't cache error responses
159
- else if (response.status >= 400) {
160
- headers.set("Cache-Control", "no-store");
161
- }
184
+ `s-maxage` gives up the split: every directive becomes visible to clients, and
185
+ caching at the edge without caching in the browser is no longer expressible.
186
+ Prefer Property Manager for stale serving when the property already honors
187
+ `Edge-Control`.
188
+
189
+ ### Vary suppresses caching
190
+
191
+ The `vary` option is off by default because of a behavior specific to Akamai:
192
+ the edge skips caching any response carrying a `Vary` header until Cache ID
193
+ Modification is configured in Property Manager. Turning `vary` on can therefore
194
+ disable edge caching entirely while every response still looks correct. The
195
+ policy logs a warning when `vary` is set together with `cdn: akamai`.
196
+
197
+ If a response genuinely varies by a request header, put that header in the cache
198
+ key with
199
+ [Cache ID Modification](https://techdocs.akamai.com/property-mgr/docs/cache-id-modification)
200
+ instead of relying on `Vary`. Cache-key configuration is not expressible in
201
+ response headers and stays CDN configuration.
202
+
203
+ ### Purge tag limits
204
+
205
+ Tags are validated against Akamai's limits before they are emitted, because the
206
+ failure mode at the edge is silent truncation rather than an error.
207
+
208
+ | Limit | Akamai value |
209
+ | ------------------------- | -------------------------------- |
210
+ | Maximum tag length | 128 characters |
211
+ | Maximum tags per response | 128 |
212
+ | Maximum header size | 8192 bytes |
213
+ | Disallowed characters | spaces, commas, colons, brackets |
214
+
215
+ A static tag in `config/policies.json` that violates a limit is a configuration
216
+ error you fix before deploying. A tag produced at request time is dropped and
217
+ logged as a warning instead.
218
+
219
+ ## Purge by tag with Fast Purge
220
+
221
+ Tagging responses is what makes targeted invalidation possible. A city sync that
222
+ changes one record can invalidate `city-42` across every edge server, leaving
223
+ the rest of the catalog cached. Without tags, the choices are waiting out the
224
+ TTL or purging far more than changed.
225
+
226
+ The policy emits the tags. It does not purge. Invalidation is a
227
+ [Fast Purge](https://techdocs.akamai.com/purge-cache/docs) API call from your
228
+ own tooling: a webhook on a content change, a step at the end of a sync job, or
229
+ an operator-run script. Point it at the
230
+ [invalidate-by-tag endpoint](https://techdocs.akamai.com/purge-cache/reference/post-invalidate-tag)
231
+ with the same tag strings the policy emits.
232
+
233
+ Two Akamai details worth knowing:
234
+
235
+ - Akamai strips `Edge-Cache-Tag` from responses before they reach end users
236
+ unless the
237
+ [Cache Tag Visibility](https://techdocs.akamai.com/property-mgr/docs/cache-tag-visibility)
238
+ behavior is enabled. Enable it temporarily to confirm tags are landing, then
239
+ turn it back off.
240
+ - Tag names must respect the charset and limits above. See Akamai's guide to
241
+ [assigning cache tags](https://techdocs.akamai.com/purge-cache/docs/assign-cache-tags).
242
+
243
+ ## Per-response cache rules
244
+
245
+ Static options cover a route. Per-entity tags such as `city-42`, a TTL that
246
+ depends on a response header, or refusing to cache an empty result set cannot be
247
+ expressed statically. For those, the policy takes a `cacheConfig` function that
248
+ returns cache intent per response, and falls back to the static options whenever
249
+ the function returns nothing.
250
+
251
+ The function returns intent rather than headers, so the same module works
252
+ unchanged if the CDN in front of the gateway changes. See
253
+ [Per-response cache rules](../../caching/dynamic-cache-rules.mdx) for the
254
+ contract, the return values, and worked examples.
255
+
256
+ ## Configure Property Manager
257
+
258
+ None of the headers above matter until the property is configured to act on
259
+ them. This is the part you cannot do from Zuplo.
260
+
261
+ 1. **Caching behavior.** Set the Caching Option to "Honor origin Cache-Control
262
+ and Expires" and enable the directives you want honored (`max-age`,
263
+ `s-maxage`, `no-store`, `private`, `must-revalidate`). Without this the
264
+ property applies its own fixed TTL and ignores what the gateway sends.
265
+ 2. **Honor `Edge-Control`.** Confirm with your Akamai team that the property
266
+ acts on `Edge-Control`. `Edge-Control: cache-maxage` outranks `Cache-Control`
267
+ at the edge, which is what keeps the edge TTL out of the client's copy. If
268
+ the property ignores it, set `strategy` to `s-maxage` until it is enabled.
269
+ 3. **Default Max-age.** Set a fallback TTL for responses that arrive with no
270
+ cache headers, such as routes that do not carry the policy.
271
+ 4. **Cache ID Modification.** Configure this if a response varies by a request
272
+ header. It is also the prerequisite for caching any response that carries a
273
+ `Vary` header.
274
+ 5. **Cache Tag Visibility.** Off by default, which keeps `Edge-Cache-Tag`
275
+ internal. Turn it on only while verifying that tags reach the edge.
162
276
 
163
- return new Response(response.body, {
164
- status: response.status,
165
- statusText: response.statusText,
166
- headers,
167
- });
168
- }
169
- ```
277
+ For detailed CDN setup instructions, see [Setting up Akamai CDNs](./cdn.mdx).
170
278
 
171
279
  ## Downstream cacheability
172
280
 
173
- By default, Akamai sends the smaller of the origin's `Cache-Control` max-age and
174
- the remaining edge cache lifetime to clients. This ensures browsers don't cache
175
- content longer than it remains valid at the edge.
176
-
177
- You can control downstream (client) caching independently using Property Manager
178
- settings or by setting explicit `max-age` values in your `Cache-Control` header.
281
+ By default, Akamai sends clients the smaller of the origin's `Cache-Control`
282
+ `max-age` and the remaining edge cache lifetime, so browsers never cache content
283
+ longer than it remains valid at the edge. With the policy in place, the origin
284
+ `max-age` is whatever `client.maxAge` sets; the edge TTL lives in `Edge-Control`
285
+ and never reaches the client at all.
179
286
 
180
- For more information, see
287
+ Property Manager's downstream cacheability settings can override this. For more
288
+ information, see
181
289
  [Akamai's downstream cacheability documentation](https://techdocs.akamai.com/property-mgr/docs/downstream-cacheability).
182
290
 
183
291
  ## Best practices
184
292
 
185
- 1. **Use s-maxage for CDN caching** - Separate CDN and browser cache durations
186
- for better control
187
- 2. **Don't cache authenticated responses** - Use `private` or `no-store` for
188
- user-specific data
189
- 3. **Set appropriate Vary headers** - If responses vary by header (like
190
- `Accept-Language`), include a `Vary` header
191
-
192
- ## Akamai Property Manager configuration
193
-
194
- For Zuplo to control caching via headers, ensure your Akamai CDN property is
195
- configured to honor origin headers:
196
-
197
- 1. In Property Manager, navigate to your property's caching behavior
198
- 2. Set **Caching Option** to "Honor origin Cache-Control and Expires"
199
- 3. Enable the Cache-Control directives you want to honor (max-age, s-maxage,
200
- etc.)
201
- 4. Set a **Default Max-age** as a fallback when origin headers are missing
202
-
203
- For detailed CDN setup instructions, see [Setting up Akamai CDNs](./cdn.mdx).
293
+ 1. **Make the client TTL much shorter than the edge TTL.** The edge is what you
294
+ can purge; clients are not. A short `client.maxAge` with a long `edge.maxAge`
295
+ gives you offload and control at the same time.
296
+ 2. **Tag by entity, not just by route.** `city-42` lets you purge one city;
297
+ `cities` alone forces you to purge them all.
298
+ 3. **Leave `respectUpstream` on** so the application keeps the ability to mark a
299
+ response uncacheable.
300
+ 4. **Verify at the edge, not just at the gateway.** `curl -I` against the Zuplo
301
+ URL shows the headers the policy emits. Whether Akamai honors them depends on
302
+ the property configuration above.
204
303
 
205
304
  ## Related resources
206
305
 
207
- - [Set Headers Policy](../../policies/set-headers-outbound.mdx) - Add headers to
208
- responses
209
- - [Caching Policy](../../policies/caching-inbound.mdx) - Zuplo's built-in
210
- response caching
211
- - [Akamai Caching Documentation](https://techdocs.akamai.com/property-mgr/docs/caching-2) -
212
- Complete Akamai caching reference
306
+ - [Cache at the CDN](../../caching/cdn-caching.mdx) the CDN Cache Control
307
+ policy across every supported CDN
308
+ - [Caching in Zuplo](../../caching/overview.mdx) where to cache, and how to
309
+ choose
310
+ - [CDN Cache Control policy](../../policies/cdn-cache-control-outbound.mdx)
311
+ every configuration option in detail
312
+ - [Caching policy](../../policies/caching-inbound.mdx) — the gateway-side
313
+ alternative, not to be combined with CDN Cache Control
314
+ - [Akamai caching documentation](https://techdocs.akamai.com/property-mgr/docs/caching-2)
315
+ — the complete Akamai caching reference
316
+ - [Akamai Fast Purge](https://techdocs.akamai.com/purge-cache/docs) — purge by
317
+ tag from your own tooling
@@ -11,7 +11,7 @@ get started.
11
11
 
12
12
  ## Prerequisites
13
13
 
14
- - [Node.js](https://nodejs.org) `>=v22.7.0` (or `>=20.19` will work as well)
14
+ - [Node.js](https://nodejs.org) `>=v24.0.0`
15
15
  - [Git](https://git-scm.com)
16
16
 
17
17
  ## Getting Started
@@ -214,7 +214,7 @@ process, continue with the manual migration steps below.
214
214
  },
215
215
  "devDependencies": {
216
216
  "typescript": "^5",
217
- "@types/node": "^22",
217
+ "@types/node": "^24",
218
218
  "@types/react": "^19",
219
219
  "@types/react-dom": "^19"
220
220
  }
@@ -28,7 +28,7 @@ Portal UI.
28
28
 
29
29
  ## Prerequisites
30
30
 
31
- - [Node.js](https://nodejs.org/en/download) 20 or higher.
31
+ - [Node.js](https://nodejs.org/en/download) 24 or higher.
32
32
  - A local Zuplo project. Create an empty one with:
33
33
 
34
34
  ```bash
@@ -58,13 +58,15 @@
58
58
  "type": "string",
59
59
  "x-show-example": false,
60
60
  "x-advanced": true,
61
- "description": "The ID of the API Key service bucket. Preferred over bucketName. Defaults to the autogenerated bucket ID for your project."
61
+ "description": "The ID of the API Key service bucket. Defaults to the autogenerated bucket ID for your project."
62
62
  },
63
63
  "bucketName": {
64
64
  "type": "string",
65
65
  "x-show-example": false,
66
66
  "x-advanced": true,
67
- "description": "The name of the API Key service bucket. Defaults to the autogenerated bucket name for your project."
67
+ "deprecated": true,
68
+ "doNotSuggest": true,
69
+ "description": "\\*\\*Deprecated\\*\\*: Use `bucketId` instead. The name of the API Key service bucket."
68
70
  },
69
71
  "allowUnauthenticatedRequests": {
70
72
  "type": "boolean",
@@ -184,3 +184,10 @@ const cachedResponse = new Response(response, {
184
184
  // Add the response to the cache
185
185
  await cache.put(request, cachedResponse);
186
186
  ```
187
+
188
+ ## See Also
189
+
190
+ - [Caching in Zuplo](../caching/overview.mdx) - Where the programmable cache
191
+ sits relative to the CDN, gateway, and client caches
192
+ - [Build a custom caching policy](../caching/custom-caching-policy.mdx) - A
193
+ worked inbound and outbound policy pair built on `caches.open`
@@ -94,3 +94,5 @@ export default async function handler(
94
94
  - [ZoneCache](./zone-cache.mdx) - For distributed caching across zones
95
95
  - [StreamingZoneCache](./streaming-zone-cache.mdx) - For caching streaming data
96
96
  - [BackgroundLoader](./background-loader.mdx) - For automatic cache population
97
+ - [Cache part of a response](../caching/partial-response-caching.mdx) - Choosing
98
+ between this cache and ZoneCache for a cached response fragment
@@ -142,5 +142,7 @@ export default async function handler(
142
142
  - [ZoneCache](./zone-cache.mdx) - For caching JSON and other structured data
143
143
  - [MemoryZoneReadThroughCache](./memory-zone-read-through-cache.mdx) - For
144
144
  in-memory caching
145
+ - [Caching in Zuplo](../caching/overview.mdx) - Where the programmable cache
146
+ sits relative to the CDN and gateway caches
145
147
  - [Web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) -
146
148
  MDN documentation on streams
@@ -141,3 +141,10 @@ For full Zuplo platform limits see the
141
141
 
142
142
  - Maximum size per cached item: 512 MB
143
143
  - Maximum cache calls per request: 1000
144
+
145
+ ## See Also
146
+
147
+ - [Cache part of a response](../caching/partial-response-caching.mdx) - Cache a
148
+ shared fragment in ZoneCache and fetch only the caller-specific slice
149
+ - [Caching in Zuplo](../caching/overview.mdx) - How ZoneCache compares to the
150
+ CDN, gateway, and client caching layers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zuplo",
3
- "version": "7.0.0",
3
+ "version": "7.0.1",
4
4
  "type": "module",
5
5
  "description": "The programmable API Gateway",
6
6
  "author": "Zuplo, Inc.",
@@ -19,9 +19,9 @@
19
19
  "zuplo": "zuplo.js"
20
20
  },
21
21
  "dependencies": {
22
- "@zuplo/cli": "7.0.0",
23
- "@zuplo/core": "7.0.0",
24
- "@zuplo/runtime": "7.0.0",
25
- "@zuplo/test": "7.0.0"
22
+ "@zuplo/cli": "7.0.1",
23
+ "@zuplo/core": "7.0.1",
24
+ "@zuplo/runtime": "7.0.1",
25
+ "@zuplo/test": "7.0.1"
26
26
  }
27
27
  }