New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

serverless-api-gateway-caching

Package Overview
Dependencies
Maintainers
1
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

serverless-api-gateway-caching - npm Package Compare versions

Comparing version 1.0.0-rc9 to 1.0.0

.circleci/config.yml

30

package.json
{
"name": "serverless-api-gateway-caching",
"version": "1.0.0-rc9",
"description": "",
"version": "1.0.0",
"description": "A plugin for the serverless framework which helps with configuring caching for API Gateway endpoints.",
"main": "src/apiGatewayCachingPlugin.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "mocha --recursive test/**/*.js -t 5000"
},
"keywords": [
"serverless",
"aws",
"api",
"gateway",
"rest",
"response",
"caching"
],
"author": "Diana Ionita",

@@ -13,4 +22,19 @@ "license": "ISC",

"aws-sdk": "^2.310.0",
"lodash.get": "^4.4.2",
"lodash.isempty": "^4.4.0"
},
"bugs": {
"url": "https://github.com/DianaIonita/serverless-api-gateway-caching/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/DianaIonita/serverless-api-gateway-caching"
},
"devDependencies": {
"aws-sdk-mock": "^4.1.0",
"chai": "^4.1.2",
"chance": "^1.0.16",
"mocha": "^5.2.0",
"mocha-junit-reporter": "^1.18.0"
}
}
# serverless-api-gateway-caching
[![CircleCI](https://circleci.com/gh/DianaIonita/serverless-api-gateway-caching.svg?style=svg)](https://circleci.com/gh/DianaIonita/serverless-api-gateway-caching)
## Intro
A plugin for the serverless framework which helps with configuring caching for API Gateway endpoints.
## Good to know
If you enable caching globally, it does NOT automatically enable caching for your endpoints - you have to be explicit about which endpoints should have caching enabled.
However, disabling caching globally disables it across endpoints.
## Example

@@ -16,4 +22,4 @@

enabled: true
clusterSize: '0.5'
ttlInSeconds: 300
clusterSize: '0.5' # defaults to '0.5'
ttlInSeconds: 300 # defaults to the maximum allowed: 3600

@@ -32,3 +38,3 @@ functions:

# Responses are cached based the 'pawId' path parameter and the 'Accept-Language' header
# Responses are cached based on the 'pawId' path parameter and the 'Accept-Language' header
get-cat-by-paw-id:

@@ -49,1 +55,7 @@ handler: rest_api/cat/get/handler.handle

```
## Limitations
* For HTTP method `ANY`, caching will be enabled only for the `GET` method and disabled for the other methods.
## Currently not supported:
* lambda functions with many http events

19

src/apiGatewayCachingPlugin.js

@@ -20,10 +20,6 @@ 'use strict';

createSettings() {
this.settings = new ApiGatewayCachingSettings(this.serverless);
this.settings = new ApiGatewayCachingSettings(this.serverless, this.options);
}
updateCloudFormationTemplate() {
if (!this.settings.cachingEnabled) {
return;
}
let restApiId = {

@@ -39,2 +35,7 @@ Ref: 'ApiGatewayRestApi',

};
// if caching is not defined or disabled
if (!this.settings.cachingEnabled) {
return;
}

@@ -45,9 +46,3 @@ return addPathParametersCacheConfig(this.settings, this.serverless);

updateStage() {
if (!this.settings.cachingEnabled) {
return;
}
serverless.cli.log(`[serverless-api-gateway-caching] Updating API Gateway cache settings.`);
return updateStageCacheSettings(this.settings, this.serverless).then(() => {
serverless.cli.log(`[serverless-api-gateway-caching] Done updating API Gateway cache settings.`);
});
return updateStageCacheSettings(this.settings, this.serverless);
}

@@ -54,0 +49,0 @@ }

const isEmpty = require('lodash.isempty');
const get = require('lodash.get');

@@ -11,4 +12,5 @@ class ApiGatewayEndpointCachingSettings {

this.cachingEnabled = false;
return;
}
this.cachingEnabled = cachingConfig.enabled;
this.cachingEnabled = globalSettings.cachingEnabled ? cachingConfig.enabled : false;
this.cacheTtlInSeconds = cachingConfig.ttlInSeconds || globalSettings.cacheTtlInSeconds;

@@ -20,12 +22,23 @@ this.cacheKeyParameters = cachingConfig.cacheKeyParameters;

class ApiGatewayCachingSettings {
constructor(serverless) {
if (!serverless.service.custom.apiGatewayCaching) {
this.cachingEnabled = false;
constructor(serverless, options) {
const DEFAULT_CACHE_CLUSTER_SIZE = '0.5';
const DEFAULT_TTL = 3600;
if (!get(serverless, 'service.custom.apiGatewayCaching')) {
return;
}
this.cachingEnabled = serverless.service.custom.apiGatewayCaching.enabled;
this.cacheClusterSize = serverless.service.custom.apiGatewayCaching.clusterSize;
this.cacheTtlInSeconds = serverless.service.custom.apiGatewayCaching.ttlInSeconds;
if (options) {
this.stage = options.stage || serverless.service.provider.stage;
this.region = options.region || serverless.service.provider.region;
} else {
this.stage = serverless.service.provider.stage;
this.region = serverless.service.provider.region;
}
this.endpointSettings = [];
this.cacheClusterSize = serverless.service.custom.apiGatewayCaching.clusterSize || DEFAULT_CACHE_CLUSTER_SIZE;
this.cacheTtlInSeconds = serverless.service.custom.apiGatewayCaching.ttlInSeconds || DEFAULT_TTL;
for (let functionName in serverless.service.functions) {

@@ -40,8 +53,8 @@ let functionSettings = serverless.service.functions[functionName];

isApiGatewayEndpoint(functionSettings) {
if (!isEmpty(functionSettings.events)) {
if (isEmpty(functionSettings.events)) {
return false;
}
return !isEmpty(functionSettings.events.filter(e => e.http != null));
return functionSettings.events.filter(e => e.http != null).length > 0;
}
}
module.exports = ApiGatewayCachingSettings

@@ -23,4 +23,4 @@ const isEmpty = require('lodash.isempty');

const getApiGatewayMethodFor = (functionName, serverless) => {
const fullFunctionName = `${serverless.service.service}-${serverless.service.custom.stage}-${functionName}`;
const getApiGatewayMethodFor = (functionName, stage, serverless) => {
const fullFunctionName = `${serverless.service.service}-${stage}-${functionName}`;
const lambdaFunctionResource = getResourceForLambdaFunctionNamed(fullFunctionName, serverless);

@@ -43,3 +43,3 @@

}
const method = getApiGatewayMethodFor(endpointSettings.functionName, serverless);
const method = getApiGatewayMethodFor(endpointSettings.functionName, settings.stage, serverless);
if (!method.resource.Properties.Integration.CacheKeyParameters) {

@@ -46,0 +46,0 @@ method.resource.Properties.Integration.CacheKeyParameters = [];

const isEmpty = require('lodash.isempty');
const AWS = require('aws-sdk');
const getRestApiId = async serverless => {
const stackName = serverless.providers.aws.naming.getStackName(serverless.service.provider.stage);
const getRestApiId = async (settings, serverless) => {
const stackName = serverless.providers.aws.naming.getStackName(settings.stage);
let stack = await serverless.providers.aws.request('CloudFormation', 'describeStacks', { StackName: stackName },
serverless.service.provider.stage,
serverless.service.provider.region
settings.stage,
settings.region
);

@@ -34,19 +34,19 @@

const createPatchForStage = (settings) => {
return [
{
let patch = [{
op: 'replace',
path: '/cacheClusterEnabled',
value: `${settings.cachingEnabled}`
}]
if (settings.cachingEnabled) {
patch.push({
op: 'replace',
path: '/cacheClusterEnabled',
value: `${settings.cachingEnabled}`
},
{
op: 'replace',
path: '/cacheClusterSize',
value: `${settings.cacheClusterSize}`
}
]
});
}
return patch;
}
const createPatchForEndpoint = (endpointSettings, serverless) => {
const patchPath = patchPathFor(endpointSettings, serverless);
if (!patchPath) return [];
const patchForMethod = (path, method, endpointSettings) => {
let patchPath = patchPathFor(path, method);
let patch = [{

@@ -56,3 +56,3 @@ op: 'replace',

value: `${endpointSettings.cachingEnabled}`
}]
}];
if (endpointSettings.cachingEnabled) {

@@ -68,3 +68,3 @@ patch.push({

const patchPathFor = (endpointSettings, serverless) => {
const createPatchForEndpoint = (endpointSettings, serverless) => {
let lambda = serverless.service.getFunction(endpointSettings.functionName);

@@ -80,4 +80,25 @@ if (isEmpty(lambda.events)) {

let { path, method } = httpEvents[0].http;
let patch = [];
if (method.toUpperCase() == 'ANY') {
let httpMethodsToDisableCacheFor = ['DELETE', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT']; // TODO could come from settings, vNext
for (let methodWithCacheDisabled of httpMethodsToDisableCacheFor) {
patch = patch.concat(patchForMethod(path, methodWithCacheDisabled,
{ cachingEnabled: false }));
};
patch = patch.concat(patchForMethod(path, 'GET', endpointSettings));
}
else {
patch = patch.concat(patchForMethod(path, method, endpointSettings));
}
return patch;
}
const patchPathFor = (path, method) => {
let escapedPath = escapeJsonPointer(path);
let patchPath = `~1${escapedPath}/${method.toUpperCase()}`;
if (!escapedPath.startsWith('~1')) {
escapedPath = `~1${escapedPath}`;
}
let patchPath = `${escapedPath}/${method.toUpperCase()}`;
return patchPath;

@@ -87,9 +108,20 @@ }

const updateStageCacheSettings = async (settings, serverless) => {
let restApiId = await getRestApiId(serverless);
// do nothing if caching settings are not defined
if (settings.cachingEnabled == undefined) {
return;
}
let restApiId = await getRestApiId(settings, serverless);
AWS.config.update({
region: serverless.service.custom.region,
region: settings.region,
});
let patchOps = createPatchForStage(settings);
let endpointsWithCachingEnabled = settings.endpointSettings.filter(e => e.cachingEnabled);
if (settings.cachingEnabled && isEmpty(endpointsWithCachingEnabled)) {
serverless.cli.log(`[serverless-api-gateway-caching] [WARNING] API Gateway caching is enabled but none of the endpoints have caching enabled`);
}
for (let endpointSettings of settings.endpointSettings) {

@@ -102,8 +134,11 @@ let endpointPatch = createPatchForEndpoint(endpointSettings, serverless);

restApiId,
stageName: serverless.service.custom.stage,
stageName: settings.stage,
patchOperations: patchOps
}
serverless.cli.log(`[serverless-api-gateway-caching] Updating API Gateway cache settings.`);
await apiGateway.updateStage(params).promise();
serverless.cli.log(`[serverless-api-gateway-caching] Done updating API Gateway cache settings.`);
}
module.exports = updateStageCacheSettings;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc