Response-Cache-Middleware
cached umschließt einen Handler mit Response-Caching,
key’d über eine vom Nutzer übergebene key(req)-Funktion. Ein
Cache-Treffer liefert die gespeicherte Response, ohne den
darunterliegenden Handler aufzurufen.
import { cached, path, get } from 'actor-ts/http';import { InMemoryCache } from 'actor-ts';
const productCache = cached({ cache: new InMemoryCache(), ttlMs: 30_000, key: (req) => `products:${pathParam(req, 'id')}`,});
const routes = path('api', path('products', get(productCache(async (req) => /* teures Lookup */)), ),);30 Sekunden pro Produkt-ID cachen. Der erste Request trifft den Handler; spätere GETs in den nächsten 30 s liefern die gecachte Response zurück.
Konfiguration
Abschnitt betitelt „Konfiguration“interface ResponseCacheOptions { cache: Cache; ttlMs: number; key: (req: HttpRequest) => string | Promise<string>; keyPrefix?: string; // Default 'rsp:' cacheStatuses?: ReadonlyArray<number>; // Default [200]}| Feld | Zweck |
|---|---|
cache | Das Cache-Backend. InMemoryCache für Single-Node; Redis für geteilt. |
ttlMs | Wie lange jede gecachte Response gültig bleibt. |
key(req) | Leitet den Cache-Key aus dem Request her — typischerweise inklusive URL-Params, Mandanten-ID, Accept-Header usw. Erforderlich. |
keyPrefix | Cache-Key-Namespace. Default 'rsp:', damit mehrere Response-Caches im selben Redis nicht kollidieren. |
cacheStatuses | Welche Statuscodes gecacht werden. Default [200] — nur 2xx-Responses landen im Cache. |
Zusammensetzung des Cache-Keys
Abschnitt betitelt „Zusammensetzung des Cache-Keys“Der Default-Key:
GET <pathname>?<sortierte-query-params> [Vary: accept=..., accept-encoding=...]Sortierte Query-Parameter sorgen dafür, dass /items?a=1&b=2 und
/items?b=2&a=1 denselben Cache-Eintrag treffen.
Mit key für per-User- / per-Mandant-Caches anpassen:
cached({ cache, ttlMs: 30_000, key: (req) => req.headers['x-tenant-id'] ?? 'public',})(...)Jetzt bekommen verschiedene Mandanten getrennte Cache-Einträge.
Wann cachen
Abschnitt betitelt „Wann cachen“GET /api/products → cachen (stabil, leselastig)POST /api/orders → nicht cachen (Mutation)GET /api/users/me → standardmäßig nicht cachen (pro User)GET /api/feed?cursor=X → cachen (ein Eintrag pro Cursor)Die Middleware cached standardmäßig nur GETs. Mutationen
(POST / PUT / DELETE / PATCH) gehen unverändert durch.
Cache-Invalidierung
Abschnitt betitelt „Cache-Invalidierung“Die Middleware invalidiert nicht automatisch bei Writes. Caching verlässt sich auf TTL-Ablauf.
Für stärkere Konsistenz zwei Muster:
Kurze TTLs
Abschnitt betitelt „Kurze TTLs“cached({ cache, ttlMs: 1_000 }); // 1 SekundeSub-Sekunden-TTLs begrenzen die Veraltung. Gut für “Echtzeit-ähnliche” APIs.
Manuelle Invalidierung
Abschnitt betitelt „Manuelle Invalidierung“// Nach einem Write, der /api/products betrifft:await cache.delete('GET:/api/products');Die Middleware exponiert den Cache; du kannst spezifische Keys
mit delete invalidieren. Nützlich für Muster wie “Write nach
/products invalidiert die Liste”.
Geteilter Cache über Pods
Abschnitt betitelt „Geteilter Cache über Pods“import { RedisCache } from 'actor-ts';
cached({ cache: new RedisCache({ url: 'redis://...' }), ttlMs: 30_000,})(...)Mit einem Redis-gestützten Cache teilen sich alle Pods denselben Cache — nützlich für Multi-Pod-Deployments, wenn du konsistentes Caching willst.
Bei Per-Pod-Caches (jeder Pod hat seinen eigenen InMemoryCache) liefern Pods kurz unterschiedliche gecachte Responses, bis die TTLs ausgerichtet sind. Oft akzeptabel; abhängig von den Konsistenzanforderungen.
Vary-Header
Abschnitt betitelt „Vary-Header“cached({ cache, ttlMs: 30_000, varyHeaders: ['accept', 'accept-language', 'x-tenant-id'],});Jede einzigartige Kombination dieser Header bekommt einen eigenen Cache-Eintrag. Nützlich für:
- Content-Negotiation — JSON-vs.-CBOR-Responses getrennt gecacht.
- Lokalisierung — Responses pro Sprache.
- Multi-Tenancy — Alternative zu
key.
Wohin als Nächstes
Abschnitt betitelt „Wohin als Nächstes“- HTTP-Übersicht — das große Bild.
- Rate-Limit-Middleware — komplementäre Middleware.
- Idempotency-Key-Middleware — für Write-Dedup.
- Cache-Übersicht — das Backend, das diese Middleware nutzt.