This is a sample repository on how to scalably implement versioning within Amazon API Gateway. This approach uses the Amazon API Gateway Custom Domain feature to implement path based routing to versioned API's.
[[TOC]]
This approach:
- Allows for versions to be deployed or removed independently (each API Version is a separate CloudFormation stack)
- Scales to 200 live versions (AWS quota, cannot be increased)
- Is completely serverless (pay as you go, scales to 0)
- Integrates with virtually any backend (AWS Lambda, Fargate, EC2, AWS Service Integrations, etc.)
This repository has an example implementation of the recommended approach to implement path based versioning with Amazon API Gateway. This repository can be utilized to deploy a sample proof-of-concept to explore the design and understand any limitations.
Deployment of this sample implementation and the use of the Amazon API Gateway Custom Domain feature requires ownership of a domain. Going through the process of purchasing ownership of a public domain is not in scope of this repository. In order to utilize this sample repository or use the Amazon API Gateway Custom Domain functionality, you must own a domain. We recommend Amazon Route 53 to create and manage your domains. More details on how to register or transfer a domain into Amazon Route 53 can be found here.
See the architecture diagram for which resources are included in the deployment of the sample application.
The sample application includes 3 stacks:
Stack | Description | Command to Deploy |
---|---|---|
CustomDomainRouterStack | Creates an ACM Certificate and Custom Domain Resource | npm run deploy-routing |
ApiStackV1 | V1 API with a API Mapping for paths that include api/v1 | npm run deploy-v1 |
ApiStackV2 | V2 API with a API Mapping for paths that include api/v2 | npm run deploy-v2 |
- Clone the repository
- Install dependencies
npm install
- Deploy the CustomDomainRouterStack CloudFormation Stack
npm run deploy-routing
- This deployment will remain a status of IN_PROGRESS until you validate the domain ownership by creating the appropriate CNAME records. More Information here
- Deploy ApiStackV1 CloudFormation Stack
npm run deploy-v1
- Deploy ApiStackV1 CloudFormation Stack
npm run deploy-v2
- Invoke your API See Testing your Sample API for more Details.
We recommend using the open-source API testing tool known as (Bruno)[https://www.usebruno.com/]. A sample collection is provided to facilite testing your Sample API. Follow these steps to invoke your API.
- Install Bruno.
- Open Bruno.
- Open Collection provided in this repository (Select folder "Sample-API-Gateway-Custom-Domain-Versioning under the Bruno folder).
- Select any request in the collection to bring up the "Environments" dropdown in the top right of the UI.
- In the Environments dropdown, select "Configure".
- Update the REPLACE_ME_WITH_YOUR_DOMAIN value with your custom domain.
- Hit Save and Close the Configuration Section.
- Ensure the Sandbox Environment is Active (selected).
- Invoke your API using the '->' button for the selected request.
- Take note on how Validation (passing in non-number values) is handled in V1 compared to V2.
Example API Invocation with Bruno:
V1 (lack of) Validation Example:
V2 (implemented) Validation Example:
The sample CDK application uses CDK nag with AWSSolutionsChecks to help improve security. However, some CDK issues are suppressed in order to keep the sample proof-of-concept application simple to use. These suppressions should be remediated before use in a production-ready implementation.
These suppressions include:
// lib/constructs/nodejsFunctionWithRole.ts
NagSuppressions.addResourceSuppressions(
this,
[
{
id: "AwsSolutions-IAM5",
reason:
"The Lambda Execution Role Policy needs to include a * permissions to enable Cloudwatch Logging and X-Ray Tracing.",
},
],
true
);
// lib/apiStackV1.ts and lib/apiStackV2.ts
NagSuppressions.addResourceSuppressions(
this.lambdaRestApi,
[
{
id: "AwsSolutions-APIG2",
reason: "Request Validation is handled by the Backend Lambda function.",
},
{
id: "AwsSolutions-APIG3",
reason:
"This API does not implement a WAF Firewall integration as it is used for demo sample implementation purposes only. Adding a firewall would add complexity to the sample proof of concept exercise. Consider adding an AWS WAF Firewall integration before using Amazon API Gateway in a production use-case.",
},
{
id: "AwsSolutions-APIG4",
reason:
"This API does not implement authorization as it is used for demo sample implementation purposes only. Adding authorization would add complexity to the sample proof of concept exercise. Ensure authorization is implemented before using Amazon API Gateway in a production use-case.",
},
{
id: "AwsSolutions-COG4",
reason:
"This API does not implement authorization as it is used for demo sample implementation purposes only. Adding authorization would add complexity to the sample proof of concept exercise. Ensure authorization is implemented before using Amazon API Gateway in a production use-case.",
},
],
true
);
See details in CONTRIBUTING.md
See details in LICENSE