serverless-api-gateway-caching
Advanced tools
Comparing version 1.1.6 to 1.2.0
{ | ||
"name": "serverless-api-gateway-caching", | ||
"version": "1.1.6", | ||
"version": "1.2.0", | ||
"description": "A plugin for the serverless framework which helps with configuring caching for API Gateway endpoints.", | ||
@@ -22,3 +22,4 @@ "main": "src/apiGatewayCachingPlugin.js", | ||
"lodash.get": "^4.4.2", | ||
"lodash.isempty": "^4.4.0" | ||
"lodash.isempty": "^4.4.0", | ||
"lodash.split": "^4.4.0" | ||
}, | ||
@@ -25,0 +26,0 @@ "bugs": { |
'use strict'; | ||
const ApiGatewayCachingSettings = require('./ApiGatewayCachingSettings'); | ||
const addPathParametersCacheConfig = require('./pathParametersCache'); | ||
const pathParametersCache = require('./pathParametersCache'); | ||
const updateStageCacheSettings = require('./stageCache'); | ||
@@ -38,3 +38,3 @@ const { restApiExists, outputRestApiIdTo } = require('./restApiId'); | ||
return addPathParametersCacheConfig(this.settings, this.serverless); | ||
return pathParametersCache.addPathParametersCacheConfig(this.settings, this.serverless); | ||
} | ||
@@ -41,0 +41,0 @@ |
@@ -21,7 +21,4 @@ const isEmpty = require('lodash.isempty'); | ||
const isApiGatewayEndpoint = functionSettings => { | ||
if (isEmpty(functionSettings.events)) { | ||
return false; | ||
} | ||
return functionSettings.events.filter(e => e.http != null).length > 0; | ||
const isApiGatewayEndpoint = event => { | ||
return event.http ? true: false; | ||
} | ||
@@ -47,11 +44,14 @@ | ||
class ApiGatewayEndpointCachingSettings { | ||
constructor(functionName, functionSettings, globalSettings) { | ||
constructor(customFunctionName, functionName, event, globalSettings) { | ||
this.customFunctionName = customFunctionName; | ||
this.functionName = functionName; | ||
// TODO multiple http endpoints | ||
let cachingConfig = functionSettings.events.filter(e => e.http != null)[0].http.caching; | ||
if (!cachingConfig) { | ||
this.path = event.http.path; | ||
this.method = event.http.method; | ||
if (!event.http.caching) { | ||
this.cachingEnabled = false; | ||
return; | ||
} | ||
let cachingConfig = event.http.caching; | ||
this.cachingEnabled = globalSettings.cachingEnabled ? cachingConfig.enabled : false; | ||
@@ -93,4 +93,6 @@ this.cacheTtlInSeconds = cachingConfig.ttlInSeconds || globalSettings.cacheTtlInSeconds; | ||
let functionSettings = serverless.service.functions[functionName]; | ||
if (isApiGatewayEndpoint(functionSettings)) { | ||
this.endpointSettings.push(new ApiGatewayEndpointCachingSettings(functionName, functionSettings, this)) | ||
for(let event in functionSettings.events) { | ||
if (isApiGatewayEndpoint(functionSettings.events[event])) { | ||
this.endpointSettings.push(new ApiGatewayEndpointCachingSettings(functionSettings.name, functionName, functionSettings.events[event], this)) | ||
} | ||
} | ||
@@ -97,0 +99,0 @@ } |
@@ -1,35 +0,27 @@ | ||
const isEmpty = require('lodash.isempty'); | ||
const split = require('lodash.split'); | ||
const getResourcesByType = (type, serverless) => { | ||
let result = [] | ||
const getResourcesByName = (name, serverless) => { | ||
let resourceKeys = Object.keys(serverless.service.provider.compiledCloudFormationTemplate.Resources); | ||
for (let resourceName of resourceKeys) { | ||
let resource = serverless.service.provider.compiledCloudFormationTemplate.Resources[resourceName]; | ||
if (resource.Type == type) { | ||
result.push({ name: resourceName, resource }); | ||
if (resourceName == name) { | ||
return serverless.service.provider.compiledCloudFormationTemplate.Resources[resourceName]; | ||
} | ||
} | ||
return result; | ||
} | ||
const getResourceForLambdaFunctionNamed = (fullFunctionName, serverless) => { | ||
let lambdaResource = getResourcesByType('AWS::Lambda::Function', serverless).filter(r => r.resource.Properties.FunctionName == fullFunctionName); | ||
if (isEmpty(lambdaResource)) { | ||
throw new Error('Something has gone wrong'); | ||
} | ||
return lambdaResource[0]; | ||
} | ||
const getApiGatewayMethodNameFor = (path, httpMethod) => { | ||
const pathElements = split(path,'/'); | ||
pathElements.push(httpMethod.toLowerCase()); | ||
let gatewayResourceName = pathElements | ||
.map (element => { | ||
element = element.toLowerCase(); | ||
if(element.startsWith('{')) { | ||
element = element.substring(element.indexOf('{') + 1,element.indexOf('}')) + "Var"; | ||
} | ||
//capitalize first letter | ||
return element.charAt(0).toUpperCase() + element.slice(1); | ||
}).reduce((a, b) => a + b); | ||
const getApiGatewayMethodFor = (functionName, stage, serverless) => { | ||
const fullFunctionName = `${serverless.service.service}-${stage}-${functionName}`; | ||
const lambdaFunctionResource = getResourceForLambdaFunctionNamed(fullFunctionName, serverless); | ||
// returns the first method found which depends on this lambda | ||
const methods = getResourcesByType('AWS::ApiGateway::Method', serverless); | ||
for (let method of methods) { | ||
let stringified = JSON.stringify(method); | ||
if (stringified.lastIndexOf(`"${lambdaFunctionResource.name}"`) != -1) { | ||
return method; | ||
} | ||
} | ||
gatewayResourceName = "ApiGatewayMethod" + gatewayResourceName; | ||
return gatewayResourceName; | ||
} | ||
@@ -41,21 +33,34 @@ | ||
continue; | ||
} | ||
const resourceName = getApiGatewayMethodNameFor(endpointSettings.path, endpointSettings.method); | ||
const method = getResourcesByName(resourceName,serverless); | ||
if (!method) { | ||
serverless.cli.log(`[serverless-api-gateway-caching] The method ${resourceName} couldn't be found in the | ||
compiled CloudFormation template. Caching settings will not be updated for this endpoint.`); | ||
const index = settings.endpointSettings.indexOf(endpointSettings); | ||
if(index != -1) { | ||
settings.endpointSettings.splice(index,1); | ||
} | ||
return; | ||
} | ||
const method = getApiGatewayMethodFor(endpointSettings.functionName, settings.stage, serverless); | ||
if (!method.resource.Properties.Integration.CacheKeyParameters) { | ||
method.resource.Properties.Integration.CacheKeyParameters = []; | ||
if (!method.Properties.Integration.CacheKeyParameters) { | ||
method.Properties.Integration.CacheKeyParameters = []; | ||
} | ||
if (!method.resource.Properties.Integration.RequestParameters) { | ||
method.resource.Properties.Integration.RequestParameters = {} | ||
if (!method.Properties.Integration.RequestParameters) { | ||
method.Properties.Integration.RequestParameters = {} | ||
} | ||
for (let cacheKeyParameter of endpointSettings.cacheKeyParameters) { | ||
let existingValue = method.resource.Properties.RequestParameters[`method.${cacheKeyParameter.name}`]; | ||
method.resource.Properties.RequestParameters[`method.${cacheKeyParameter.name}`] = (existingValue == null || existingValue == undefined) ? {} : existingValue; | ||
method.resource.Properties.Integration.RequestParameters[`integration.${cacheKeyParameter.name}`] = `method.${cacheKeyParameter.name}`; | ||
method.resource.Properties.Integration.CacheKeyParameters.push(`method.${cacheKeyParameter.name}`); | ||
let existingValue = method.Properties.RequestParameters[`method.${cacheKeyParameter.name}`]; | ||
method.Properties.RequestParameters[`method.${cacheKeyParameter.name}`] = (existingValue == null || existingValue == undefined) ? {} : existingValue; | ||
method.Properties.Integration.RequestParameters[`integration.${cacheKeyParameter.name}`] = `method.${cacheKeyParameter.name}`; | ||
method.Properties.Integration.CacheKeyParameters.push(`method.${cacheKeyParameter.name}`); | ||
} | ||
method.resource.Properties.Integration.CacheNamespace = `${method.name}CacheNS`; | ||
method.Properties.Integration.CacheNamespace = `${resourceName}CacheNS`; | ||
} | ||
} | ||
module.exports = addPathParametersCacheConfig; | ||
module.exports = { | ||
addPathParametersCacheConfig: addPathParametersCacheConfig, | ||
getApiGatewayMethodNameFor: getApiGatewayMethodNameFor | ||
} |
@@ -67,2 +67,8 @@ const isEmpty = require('lodash.isempty'); | ||
const httpEventOf = (lambda, endpointSettings) => { | ||
return lambda.events.filter(e => e.http != undefined) | ||
.filter(e => e.http.path === endpointSettings.path || "/" + e.http.path === endpointSettings.path) | ||
.filter(e => e.http.method === endpointSettings.method); | ||
} | ||
const createPatchForEndpoint = (endpointSettings, serverless) => { | ||
@@ -72,7 +78,8 @@ let lambda = serverless.service.getFunction(endpointSettings.functionName); | ||
serverless.cli.log(`[serverless-api-gateway-caching] Lambda ${endpointSettings.functionName} has not defined events.`); | ||
return; | ||
} | ||
// TODO there can be many http events | ||
let httpEvents = lambda.events.filter(e => e.http != null); | ||
const httpEvents = httpEventOf(lambda,endpointSettings); | ||
if (isEmpty(httpEvents)) { | ||
serverless.cli.log(`[serverless-api-gateway-caching] Lambda ${endpointSettings.functionName} has not defined any HTTP events.`); | ||
return; | ||
} | ||
@@ -79,0 +86,0 @@ let { path, method } = httpEvents[0].http; |
20014
373
3
+ Addedlodash.split@^4.4.0
+ Addedlodash.split@4.4.2(transitive)