Skip to content

Commit 3216b54

Browse files
authored
Merge pull request #19 from blastorg/7516/introduce-passthroughquerykey-on-the-fastify-dynamodb-cache
7516/introduce passthroughquerykey on the fastify dynamodb cache
2 parents e6cea93 + 7805bb7 commit 3216b54

File tree

4 files changed

+70
-2
lines changed

4 files changed

+70
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const fastify = Fastify().register(dynamodbCache, {
4141
tableName: "fastify-dynamodb-cache", // DynamoDB table name
4242
defaultTTLSeconds: 30, // Default TTL (seconds), which would be used if no TTL is specified on the endpoint.
4343
disableCache: true, // Optional! If you want to disable caching from being set on endpoints, you can set this to true. Set it to false or leave it empty to enable cache.
44+
passthroughQueryParam: "_t", // Optional! If you want to define a query parameter for all endpoints, which will be used to bypass the cache (will set 'x-cache: ignored').
4445
});
4546

4647
fastify.get(

src/helpers/hasQueryParams.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const hasQueryParam = (
2+
query: unknown,
3+
key: string
4+
): query is Record<string, unknown> => {
5+
return (
6+
typeof query === "object" &&
7+
query !== null &&
8+
!Array.isArray(query) &&
9+
key in query
10+
);
11+
};

src/hooks/onRequest.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb";
22
import { FastifyRequest, FastifyReply } from "fastify";
33
import { onRequestAsyncHookHandler } from "fastify/types/hooks";
4+
import { hasQueryParam } from "../helpers/hasQueryParams";
45

56
interface CreateOnRequestHookOptions {
67
dynamoClient: DynamoDBClient;
78
tableName: string;
9+
passthroughQueryParam?: string;
810
}
911

1012
export const createOnRequestHook = ({
1113
dynamoClient,
1214
tableName,
15+
passthroughQueryParam,
1316
}: CreateOnRequestHookOptions) => {
1417
const onRequestHook: onRequestAsyncHookHandler = async (
1518
request: FastifyRequest,
@@ -22,6 +25,14 @@ export const createOnRequestHook = ({
2225
},
2326
});
2427

28+
if (
29+
passthroughQueryParam &&
30+
hasQueryParam(request.query, passthroughQueryParam)
31+
) {
32+
reply.header("x-cache", "ignored");
33+
return;
34+
}
35+
2536
try {
2637
const { Item } = await dynamoClient.send(command);
2738

src/index.ts

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,50 @@ import fastifyPlugin from "fastify-plugin";
44
import { createOnRequestHook } from "./hooks/onRequest";
55
import { createOnSendHook } from "./hooks/onSend";
66

7-
export interface PluginOptions {
7+
/**
8+
* Plugin options for fastify-aws-dynamodb-cache.
9+
*
10+
* @property {string} dynamoDbRegion - AWS region for DynamoDB client configuration.
11+
* @property {string} [dynamoDbAddress] - Optional custom endpoint (useful for local development/testing).
12+
* @property {string} tableName - DynamoDB table name used for storing cache entries.
13+
* @property {number} defaultTTLSeconds - Global default TTL (in seconds) for all cache entries.
14+
* @property {boolean} [disableCache=false] - If true, disables caching plugin-wide.
15+
* @property {string} [passthroughQueryParam] - If defined, this query parameter will bypass cache when present in a request.
16+
*/
17+
export interface DynamodbCachePluginOptions {
818
dynamoDbRegion: string;
919
dynamoDbAddress?: string;
1020
tableName: string;
1121
defaultTTLSeconds: number;
1222
disableCache?: boolean;
23+
passthroughQueryParam?: string;
1324
}
1425

15-
export const dynamodbCache: FastifyPluginAsync<PluginOptions> = (
26+
/**
27+
* Fastify plugin for caching responses in DynamoDB.
28+
*
29+
* Adds support for per-route caching via a shared DynamoDB table.
30+
*
31+
* Use route-level `config.cache` to control TTL and caching behavior:
32+
*
33+
* @example
34+
* ```ts
35+
* fastify.get('/my-route', {
36+
* config: {
37+
* cache: {
38+
* cacheEnabled: true,
39+
* ttlSeconds: 120
40+
* }
41+
* }
42+
* }, async (req, reply) => {
43+
* return { hello: 'world' };
44+
* });
45+
* ```
46+
*
47+
* @param fastify - Fastify instance
48+
* @param opts - Plugin options for DynamoDB caching
49+
*/
50+
export const dynamodbCache: FastifyPluginAsync<DynamodbCachePluginOptions> = (
1651
fastify,
1752
opts
1853
) => {
@@ -31,6 +66,7 @@ export const dynamodbCache: FastifyPluginAsync<PluginOptions> = (
3166
const onRequestHook = createOnRequestHook({
3267
dynamoClient,
3368
tableName: opts.tableName,
69+
passthroughQueryParam: opts.passthroughQueryParam,
3470
});
3571

3672
const onSendHook = createOnSendHook({
@@ -63,8 +99,17 @@ export const dynamodbCache: FastifyPluginAsync<PluginOptions> = (
6399

64100
declare module "fastify" {
65101
interface FastifyContextConfig {
102+
/**
103+
* Route-specific cache configuration.
104+
*/
66105
cache?: {
106+
/**
107+
* Enable or disable cache for this route. Defaults to false.
108+
*/
67109
cacheEnabled?: boolean;
110+
/**
111+
* TTL in seconds for the cached response. Overrides global defaultTTLSeconds if set.
112+
*/
68113
ttlSeconds?: number;
69114
};
70115
}

0 commit comments

Comments
 (0)