Skip to content

Commit

Permalink
feat(apigateway): Adds construct which allow configuring ratelimiting…
Browse files Browse the repository at this point in the history
… at api key level

In cases when we need to configure throttling and quotas etc., at the api key level, we need to create a usage plan for the api key and link the two.
This commit introduces a construct which allows the user to create an api key and spicify rate limiting settings, while creating the api key and not worry about creating usage plan and linking the two.

fixes #6405
  • Loading branch information
Vaibhav Walia committed Mar 4, 2020
1 parent b677b31 commit 4eafcb5
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 84 deletions.
13 changes: 13 additions & 0 deletions packages/@aws-cdk/aws-apigateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,13 @@ plan.addApiStage({
});
```

<<<<<<< HEAD
=======
In scenarios where you need to create a single api key and configure rate limiting for it, you can use RateLimitedApiKey.
This construct lets you specify rate limiting properties which should be applied only to the api key being created.
Internally, it automatically creates a usage plan with the specified rate limiting properties for this api key.

>>>>>>> feat(apigateway): Adds construct which allow configuring ratelimiting at api key level
The following example shows how to use a rate limited api key :
```ts
const hello = new lambda.Function(this, 'hello', {
Expand All @@ -171,11 +178,17 @@ const echoMethod = echo.addMethod('GET', integration, { apiKeyRequired: true });
const key = new apigateway.RateLimitedApiKey(this, 'rate-limited-api-key', {
customerId: 'hello-customer',
resources: [api],
<<<<<<< HEAD
rateLimitingSettings: {
quota: {
limit: 10000,
period: apigateway.Period.MONTH
}
=======
quota: {
limit: 10000,
period: apigateway.Period.MONTH
>>>>>>> feat(apigateway): Adds construct which allow configuring ratelimiting at api key level
}
});

Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-apigateway/lib/api-key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface IApiKey extends IResourceBase {
*/
export interface ApiKeyProps extends ResourceOptions {
/**
* [disable-awslint:ref-via-interface]
* A list of resources this api key is associated with.
* @default none
*/
Expand Down
86 changes: 9 additions & 77 deletions packages/@aws-cdk/aws-apigateway/lib/rate-limited-api-key.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
import { Construct, IResource as IResourceBase, Resource } from '@aws-cdk/core';
import { ApiKey } from './api-key';
import { ResourceOptions } from "./resource";
import { RestApi } from './restapi';
import { Construct, Resource } from '@aws-cdk/core';
import { ApiKey, ApiKeyProps, IApiKey } from './api-key';
import { QuotaSettings, ThrottleSettings, UsagePlan, UsagePlanPerApiStage } from './usage-plan';

/**
* API keys are alphanumeric string values that you distribute to
* app developer customers to grant access to your API
*/
export interface IRateLimitedApiKey extends IResourceBase {
/**
* The API key ID.
* @attribute
*/
readonly keyId: string;
}

/**
* Rate limiting settings for the api key.
* RateLimitedApiKey properties.
*/
export interface RateLimitingSettings {
export interface RateLimitedApiKeyProps extends ApiKeyProps {
/**
* API Stages to be associated with the RateLimitedApiKey.
* @default none
Expand All @@ -39,66 +25,12 @@ export interface RateLimitingSettings {
readonly throttle?: ThrottleSettings;
}

/**
* RateLimitedApiKey properties.
*/
export interface RateLimitedApiKeyProps extends ResourceOptions {
/**
* [disable-awslint:ref-via-interface]
* A list of resources this api key is associated with.
*
* @default none
*/
readonly resources?: RestApi[];

/**
* An AWS Marketplace customer identifier to use when integrating with the AWS SaaS Marketplace.
* @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-customerid
* @default none
*/
readonly customerId?: string;

/**
* A description of the purpose of the API key.
* @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-description
* @default none
*/
readonly description?: string;

/**
* Indicates whether the API key can be used by clients.
* @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-enabled
* @default true
*/
readonly enabled?: boolean;

/**
* Specifies whether the key identifier is distinct from the created API key value.
* @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-generatedistinctid
* @default false
*/
readonly generateDistinctId?: boolean;

/**
* A name for the API key. If you don't specify a name, AWS CloudFormation generates a unique physical ID and uses that ID for the API key name.
* @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-name
* @default automically generated name
*/
readonly apiKeyName?: string;

/**
* Rate limiting settings to be used for this api key.
* @default none
*/
readonly rateLimitingSettings?: RateLimitingSettings;
}

/**
* An API Gateway ApiKey, for which a rate limiting configuration can be specified.
*
* @resource AWS::ApiGateway::ApiKey
*/
export class RateLimitedApiKey extends Resource implements IRateLimitedApiKey {
export class RateLimitedApiKey extends Resource implements IApiKey {
public readonly keyId: string;

constructor(scope: Construct, id: string, props: RateLimitedApiKeyProps = { }) {
Expand All @@ -118,12 +50,12 @@ export class RateLimitedApiKey extends Resource implements IRateLimitedApiKey {
resources: props.resources
});

if (props.rateLimitingSettings) {
if (props.apiStages || props.quota || props.throttle) {
new UsagePlan(this, 'UsagePlanResource', {
apiKey: resource,
apiStages: props.rateLimitingSettings.apiStages,
quota: props.rateLimitingSettings.quota,
throttle: props.rateLimitingSettings.throttle
apiStages: props.apiStages,
quota: props.quota,
throttle: props.throttle
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export = {
test.done();
},

'only api key is created when rateLimitingSettings are not provided'(test: Test) {
'only api key is created when rate limiting properties are not provided'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const api = new apigateway.RestApi(stack, 'test-api', { cloudWatchRole: false, deploy: true, deployOptions: { stageName: 'test' } });
Expand Down Expand Up @@ -58,7 +58,7 @@ export = {
test.done();
},

'api key and usage plan are created and linked when rateLimitingSettings are provided'(test: Test) {
'api key and usage plan are created and linked when rate limiting properties are provided'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const api = new apigateway.RestApi(stack, 'test-api', { cloudWatchRole: false, deploy: true, deployOptions: { stageName: 'test' } });
Expand All @@ -68,11 +68,9 @@ export = {
new apigateway.RateLimitedApiKey(stack, 'test-api-key', {
customerId: 'test-customer',
resources: [api],
rateLimitingSettings: {
quota: {
limit: 10000,
period: apigateway.Period.MONTH
}
quota: {
limit: 10000,
period: apigateway.Period.MONTH
}
});

Expand Down

0 comments on commit 4eafcb5

Please sign in to comment.