Cache Key Parameters
Define what makes a cache entry unique — path, query string, header, and body parameters.
Overview
Without cache key parameters, all requests to the same path return the same cached response. Cache key parameters tell API Gateway to create separate cache entries based on request values.
The same recipe in all four config formats Serverless Framework supports — pick whichever your project uses.
TypeScript users — typing the `caching:` field
The official @types/serverless (serverless/aws.d.ts) doesn't include a caching shape on http events — that's a plugin-level extension. Two options to keep serverless.ts clean:
-
Recommended. Import the typed shapes our plugin exports and assert at the assignment site:
import type { EndpointCachingConfig } from '@interlace/serverless-api-gateway-caching'; const caching: EndpointCachingConfig = { enabled: true, cacheKeyParameters: [{ name: 'request.path.id' }], }; // attach to the http event with `as unknown as Record<string, unknown>` // or extend the framework's `Http` type via module augmentation. -
Quick escape hatch. Inline cast:
caching: ({ enabled: true, ... } as unknown as never). Keeps the rest of the config typed; loses safety on the caching subtree only.
The TypeScript snippets below assume option 1 — replace the inline objects with values typed against EndpointCachingConfig. We're tracking native @types/serverless integration in the plugin's roadmap.
Path, Query String, and Header
functions:
listCats:
handler: src/handler.list
events:
- http:
path: /cats
method: get
caching:
enabled: true
cacheKeyParameters:
- name: request.path.id
- name: request.querystring.page
- name: request.querystring.limit
- name: request.header.Accept-Languageconst serverlessConfiguration: AWS = {
functions: {
listCats: {
handler: 'src/handler.list',
events: [
{
http: {
path: '/cats',
method: 'get',
caching: {
enabled: true,
cacheKeyParameters: [
{ name: 'request.path.id' },
{ name: 'request.querystring.page' },
{ name: 'request.querystring.limit' },
{ name: 'request.header.Accept-Language' },
],
},
},
},
],
},
},
};module.exports = {
functions: {
listCats: {
handler: 'src/handler.list',
events: [
{
http: {
path: '/cats',
method: 'get',
caching: {
enabled: true,
cacheKeyParameters: [
{ name: 'request.path.id' },
{ name: 'request.querystring.page' },
{ name: 'request.querystring.limit' },
{ name: 'request.header.Accept-Language' },
],
},
},
},
],
},
},
};{
"functions": {
"listCats": {
"handler": "src/handler.list",
"events": [
{
"http": {
"path": "/cats",
"method": "get",
"caching": {
"enabled": true,
"cacheKeyParameters": [
{ "name": "request.path.id" },
{ "name": "request.querystring.page" },
{ "name": "request.querystring.limit" },
{ "name": "request.header.Accept-Language" }
]
}
}
}
]
}
}
}How cache entries are created
Given the configuration:
caching:
enabled: true
cacheKeyParameters:
- name: request.path.pawId
- name: request.querystring.catNamecaching: {
enabled: true,
cacheKeyParameters: [
{ name: 'request.path.pawId' },
{ name: 'request.querystring.catName' },
],
}caching: {
enabled: true,
cacheKeyParameters: [
{ name: 'request.path.pawId' },
{ name: 'request.querystring.catName' },
],
}{
"caching": {
"enabled": true,
"cacheKeyParameters": [
{ "name": "request.path.pawId" },
{ "name": "request.querystring.catName" }
]
}
}GET /cats/4→ cache entry forpawId=4,catName=undefinedGET /cats/34?catName=Dixon→ cache entry forpawId=34,catName=DixonGET /cats/72?catName=Tsunami&furColour=white→ cache entry forpawId=72,catName=Tsunami(ignoresfurColour)
Cache key parameter names are case sensitive. request.header.accept-language and request.header.Accept-Language create different cache entries.
Body-Based Cache Keys
For POST endpoints (e.g., GraphQL), cache based on the request body.
Entire body
caching:
enabled: true
cacheKeyParameters:
- name: integration.request.header.bodyValue
mappedFrom: method.request.bodycaching: {
enabled: true,
cacheKeyParameters: [
{
name: 'integration.request.header.bodyValue',
mappedFrom: 'method.request.body',
},
],
}caching: {
enabled: true,
cacheKeyParameters: [
{
name: 'integration.request.header.bodyValue',
mappedFrom: 'method.request.body',
},
],
}{
"caching": {
"enabled": true,
"cacheKeyParameters": [
{
"name": "integration.request.header.bodyValue",
"mappedFrom": "method.request.body"
}
]
}
}JSONPath expression
Cache by a specific field in the body:
caching:
enabled: true
cacheKeyParameters:
- name: integration.request.header.cityCount
mappedFrom: method.request.body.cities[0].petCountcaching: {
enabled: true,
cacheKeyParameters: [
{
name: 'integration.request.header.cityCount',
mappedFrom: 'method.request.body.cities[0].petCount',
},
],
}caching: {
enabled: true,
cacheKeyParameters: [
{
name: 'integration.request.header.cityCount',
mappedFrom: 'method.request.body.cities[0].petCount',
},
],
}{
"caching": {
"enabled": true,
"cacheKeyParameters": [
{
"name": "integration.request.header.cityCount",
"mappedFrom": "method.request.body.cities[0].petCount"
}
]
}
}Mixed sources
Combine query string and body parameters:
caching:
enabled: true
cacheKeyParameters:
- name: request.querystring.catName
- name: integration.request.header.furColour
mappedFrom: method.request.body.furColourcaching: {
enabled: true,
cacheKeyParameters: [
{ name: 'request.querystring.catName' },
{
name: 'integration.request.header.furColour',
mappedFrom: 'method.request.body.furColour',
},
],
}caching: {
enabled: true,
cacheKeyParameters: [
{ name: 'request.querystring.catName' },
{
name: 'integration.request.header.furColour',
mappedFrom: 'method.request.body.furColour',
},
],
}{
"caching": {
"enabled": true,
"cacheKeyParameters": [
{ "name": "request.querystring.catName" },
{
"name": "integration.request.header.furColour",
"mappedFrom": "method.request.body.furColour"
}
]
}
}Catch-All Path Parameters
For greedy path routes ({proxy+}):
functions:
proxy:
handler: src/proxy.handle
events:
- http:
path: /api/{proxy+}
method: get
caching:
enabled: true
cacheKeyParameters:
- name: request.path.proxyfunctions: {
proxy: {
handler: 'src/proxy.handle',
events: [
{
http: {
path: '/api/{proxy+}',
method: 'get',
caching: {
enabled: true,
cacheKeyParameters: [{ name: 'request.path.proxy' }],
},
},
},
],
},
}functions: {
proxy: {
handler: 'src/proxy.handle',
events: [
{
http: {
path: '/api/{proxy+}',
method: 'get',
caching: {
enabled: true,
cacheKeyParameters: [{ name: 'request.path.proxy' }],
},
},
},
],
},
}{
"functions": {
"proxy": {
"handler": "src/proxy.handle",
"events": [
{
"http": {
"path": "/api/{proxy+}",
"method": "get",
"caching": {
"enabled": true,
"cacheKeyParameters": [{ "name": "request.path.proxy" }]
}
}
}
]
}
}
}Cache entries:
GET /api/users→proxy=usersGET /api/users/123→proxy=users/123
Limitations
- Multi-value query strings (
request.multivaluequerystring.*) and multi-value headers (request.multivalueheader.*) are not supported as cache key parameters. This is an AWS API Gateway limitation, not a plugin choice — AWS rejects these asInvalid mapping expression. The same limitation applies to the communityserverless-api-gateway-cachingplugin. - Body-based cache keys require an integration request mapping (handled automatically by the plugin).
httpApi(HTTP API) events are not supported — API Gateway HTTP APIs do not support caching (AWS docs).