Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

serverless-api-gateway-throttling

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

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

Comparing version 1.2.2 to 2.0.0-rc1

LICENSE

2

package.json
{
"name": "serverless-api-gateway-throttling",
"version": "1.2.2",
"version": "2.0.0-rc1",
"description": "A plugin for the Serverless framework which configures throttling for API Gateway endpoints.",

@@ -5,0 +5,0 @@ "main": "src/apiGatewayThrottlingPlugin.js",

@@ -14,2 +14,3 @@ # serverless-api-gateway-throttling

This plugin makes it easy to configure those limits.
It supports both API Gateway v1 (REST API) and API Gateway v2 (HTTP API).

@@ -91,10 +92,21 @@ ## Good to know

# Throttling is disabled for this endpoint
list-all-items:
list-more-items:
handler: rest_api/items/get/handler.handle
events:
- http:
path: /items
path: /more-items
method: get
throttling:
disabled: true
# Also supports httpApi
list-http-api-items:
handler: rest_api/items/get/handler.handle
events:
- httpApi:
path: /http-api-items
method: get
throttling:
maxRequestsPerSecond: 3000
maxConcurrentRequests: 1000
```

@@ -38,7 +38,15 @@ 'use strict';

if (!this.thereIsARestApi) {
this.serverless.cli.log(`[serverless-api-gateway-throttling] No REST API found. Throttling settings will be ignored.`);
return;
this.serverless.cli.log(`[serverless-api-gateway-throttling] No REST API found. Throttling settings will be ignored for REST API endpoints.`);
}
else {
outputRestApiIdTo(this.serverless);
}
outputRestApiIdTo(this.serverless);
this.thereIsAHttpApi = await httpApiExists(this.serverless);
if (!this.thereIsAHttpApi) {
this.serverless.cli.log(`[serverless-api-gateway-throttling] No HTTP API (API Gateway v2) found. Throttling settings will be ignored for HTTP API endpoints.`);
}
else {
outputHttpApiIdTo(this.serverless);
}
}

@@ -45,0 +53,0 @@

@@ -13,8 +13,12 @@ 'use strict';

const isHttpApiEndpoint = event => {
return event.httpApi ? true : false;
}
class ApiGatewayEndpointThrottlingSettings {
constructor(functionName, event, globalSettings) {
constructor(functionName, event, eventType, globalSettings) {
this.functionName = functionName;
if (typeof (event.http) === 'string') {
let parts = event.http.split(' ');
if (typeof (event[eventType]) === 'string') {
let parts = event[eventType].split(' ');
this.method = parts[0];

@@ -24,7 +28,7 @@ this.path = parts[1];

else {
this.path = event.http.path;
this.method = event.http.method;
this.path = event[eventType].path;
this.method = event[eventType].method;
}
const throttlingDisabled = get(event.http.throttling, 'disabled') == true;
const throttlingDisabled = get(event[eventType].throttling, 'disabled') == true;
if (throttlingDisabled) {

@@ -37,4 +41,4 @@ // https://github.com/DianaIonita/serverless-api-gateway-throttling/issues/5

else {
this.maxRequestsPerSecond = get(event.http.throttling, 'maxRequestsPerSecond', globalSettings.maxRequestsPerSecond);
this.maxConcurrentRequests = get(event.http.throttling, 'maxConcurrentRequests', globalSettings.maxConcurrentRequests);
this.maxRequestsPerSecond = get(event[eventType].throttling, 'maxRequestsPerSecond', globalSettings.maxRequestsPerSecond);
this.maxConcurrentRequests = get(event[eventType].throttling, 'maxConcurrentRequests', globalSettings.maxConcurrentRequests);
}

@@ -59,3 +63,4 @@ }

this.endpointSettings = [];
this.restEndpointSettings = [];
this.httpApiEndpointSettings = [];

@@ -69,4 +74,7 @@ for (let functionName in serverless.service.functions) {

if (isApiGatewayEndpoint(event)) {
this.endpointSettings.push(new ApiGatewayEndpointThrottlingSettings(functionName, event, this))
this.restEndpointSettings.push(new ApiGatewayEndpointThrottlingSettings(functionName, event, 'http', this))
}
if (isHttpApiEndpoint(event)) {
this.httpApiEndpointSettings.push(new ApiGatewayEndpointThrottlingSettings(functionName, event, 'httpApi', this))
}
}

@@ -73,0 +81,0 @@ }

@@ -38,2 +38,23 @@ String.prototype.replaceAll = function (search, replacement) {

const httpApiEventOf = (lambda, endpointSettings) => {
let httpApiEvents = lambda.events.filter(e => e.httpApi != undefined)
.map(e => {
if (typeof (e.http) === 'string') {
let parts = e.http.split(' ');
return {
method: parts[0],
path: parts[1]
}
} else {
return {
method: e.http.method,
path: e.http.path
}
}
});
return httpApiEvents.filter(e => e.path = endpointSettings.path || "/" + e.path === endpointSettings.path)
.filter(e => e.method.toUpperCase() == endpointSettings.method.toUpperCase())[0];
}
const patchPathFor = (path, method) => {

@@ -50,3 +71,4 @@ let escapedPath = escapeJsonPointer(path);

patchPathFor,
httpEventOf
httpEventOf,
httpApiEventOf
}

@@ -79,4 +79,4 @@ 'use strict';

for (const endpointSettings of settings.endpointSettings) {
const endpointPatch = createPatchForEndpoint(endpointSettings, serverless);
for (const restEndpointSettings of settings.restEndpointSettings) {
const endpointPatch = createPatchForEndpoint(restEndpointSettings, serverless);
patchOps = patchOps.concat(endpointPatch);

@@ -83,0 +83,0 @@ }

@@ -65,2 +65,7 @@ 'use strict';

const configuredRestApiId = getConfiguredRestApiId(serverless);
if (configuredRestApiId) {
return configuredRestApiId;
}
const stack = await getAlreadyDeployedStack(serverless, settings);

@@ -67,0 +72,0 @@ const outputs = stack.Stacks[0].Outputs;

'use strict';
const isEmpty = require('lodash.isempty');
const { retrieveRestApiId } = require('./restApiId');
const { httpEventOf, patchPathFor } = require('./lib');
const MAX_PATCH_OPERATIONS_PER_STAGE_UPDATE = 80;
const { updateRestApi } = require('./updateRestApiStageThrottling');
const { updateHttpApi } = require('./updateHttpApiStageThrottling');
const createPatchForStage = (settings) => {
let patch = [{
op: 'replace',
path: '/*/*/throttling/rateLimit',
value: `${settings.maxRequestsPerSecond}`
},
{
op: 'replace',
path: '/*/*/throttling/burstLimit',
value: `${settings.maxConcurrentRequests}`
}];
return patch;
}
const patchForMethod = (path, method, endpointSettings) => {
let patchPath = patchPathFor(path, method);
let patch = [{
op: 'replace',
path: `/${patchPath}/throttling/rateLimit`,
value: `${endpointSettings.maxRequestsPerSecond}`
},
{
op: 'replace',
path: `/${patchPath}/throttling/burstLimit`,
value: `${endpointSettings.maxConcurrentRequests}`
}]
return patch;
}
const createPatchForEndpoint = (endpointSettings, serverless) => {
let lambda = serverless.service.getFunction(endpointSettings.functionName);
if (isEmpty(lambda.events)) {
serverless.cli.log(`[serverless-api-gateway-throttling] Lambda ${endpointSettings.functionName} has not defined events.`);
return;
}
const httpEvent = httpEventOf(lambda, endpointSettings);
if (isEmpty(httpEvent)) {
serverless.cli.log(`[serverless-api-gateway-throttling] Lambda ${endpointSettings.functionName} has not defined any HTTP events.`);
return;
}
let { path, method } = httpEvent;
let patch = [];
if (method.toUpperCase() == 'ANY') {
let httpMethodsToConfigureThrottlingFor = ['GET', 'DELETE', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT'];
for (let methodWithThrottlingSettings of httpMethodsToConfigureThrottlingFor) {
patch = patch.concat(patchForMethod(path, methodWithThrottlingSettings, endpointSettings));
};
}
else {
patch = patch.concat(patchForMethod(path, method, endpointSettings));
}
return patch;
}
const updateStageFor = async (serverless, params, stage, region) => {
const chunkSize = MAX_PATCH_OPERATIONS_PER_STAGE_UPDATE;
const { patchOperations } = params;
const paramsInChunks = [];
if (patchOperations.length > chunkSize) {
for (let i = 0; i < patchOperations.length; i += chunkSize) {
paramsInChunks.push({
restApiId: params.restApiId,
stageName: params.stageName,
patchOperations: patchOperations.slice(i, i + chunkSize)
});
}
}
else {
paramsInChunks.push(params);
}
for (let index in paramsInChunks) {
serverless.cli.log(`[serverless-api-gateway-throttling] Updating API Gateway throttling settings (${parseInt(index) + 1} of ${paramsInChunks.length}).`);
await serverless.providers.aws.request('APIGateway', 'updateStage', paramsInChunks[index], stage, region);
}
serverless.cli.log(`[serverless-api-gateway-throttling] Done updating API Gateway throttling settings.`);
}
const updateStageThrottling = async (settings, serverless) => {

@@ -95,22 +12,6 @@ if (isEmpty(settings)) {

const restApiId = await retrieveRestApiId(serverless, settings);
let patchOps = createPatchForStage(settings);
for (const endpointSettings of settings.endpointSettings) {
const endpointPatch = createPatchForEndpoint(endpointSettings, serverless);
patchOps = patchOps.concat(endpointPatch);
}
const { stage, region } = settings;
const params = {
restApiId,
stageName: stage,
patchOperations: patchOps
}
await updateStageFor(serverless, params, stage, region);
await updateRestApi(settings, serverless);
await updateHttpApi(settings, serverless);
}
module.exports = updateStageThrottling;
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