DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Unlocking the Benefits of a Private API in AWS API Gateway
  • Building a Scalable ML Pipeline and API in AWS
  • Container Checkpointing in Kubernetes With a Custom API
  • Serverless NLP: Implementing Sentiment Analysis Using Serverless Technologies

Trending

  • Immutable Secrets Management: A Zero-Trust Approach to Sensitive Data in Containers
  • Scalable System Design: Core Concepts for Building Reliable Software
  • Google Cloud Document AI Basics
  • Emerging Data Architectures: The Future of Data Management
  1. DZone
  2. Data Engineering
  3. Databases
  4. API Versioning Approach With AWS API Gateway

API Versioning Approach With AWS API Gateway

In this post, I have tried to describe the steps and artifacts require to implement Amazon API Gateway based REST API versioning strategy.

By 
Tridib Bolar user avatar
Tridib Bolar
·
Aug. 07, 18 · Analysis
Likes (6)
Comment
Save
Tweet
Share
60.9K Views

Join the DZone community and get the full member experience.

Join For Free

Abstract

In this post, I have tried to describe the steps and artifacts require to implement Amazon API Gateway based REST API versioning strategy.

Introduction

There is a requirement to versioning the REST API in one of our projects. These REST APIs should be generic enough to support multitenancy and multiple versions. As these APIs will be used by multiple customers, there is a possibility where two different customers can use two different versions of the API simultaneously.

As we are implementing our API using the Amazon API Gateway service, and we want to implement the recommended best approach. I was in a search to figure out the best versioning strategy using AWS API Gateway and Lambda. After spending a day in search, my understanding is that there are three gross strategies to version the REST API. 1) Create a completely new API with appending the version number at the end (e.g. www.mydomain.com/ordersV1, www.mydomain.com/ordersV2 something like this), 2) Putting the version indicator in the resource path (e.g. www.mydomain.com/api/v1/xxx, www.mydomain.com/api/v2/xxx) — It's a traditional approach. and 3) Create a completely new domain for the new version (v1.api.mysite.com, v2.api.mysite.com). We have to select our approach out of these three strategies.

Solution Approach

There is an option in the AWS API Gateway named Stage Variables. Inside theIntegration Request view, we can provide the stage variable name ( ${stageVariables.<stage variable name> } ) instead of the actual Lambda function name. During deployment, the stage variable can contain a different Lambda version (or alias), so that based on invoked resource (/api/v1/getOrders), staging environment (dev, prod etc.), and lambda name with version defined in stage variable, API Gateway can choose the corresponding function to invoke. We decided to exploit this feature to go with the traditional versioning approach i.e. resource path-based versioning. The next section explains the details of the manual implementation steps of this approach.

Solution Details

I create one simple NodeJs Lambda function with two versions and then created the AWS Gateway API resources to trigger those versions. All these steps described here are executed manually. Later, we will establish the AWS CodePipeline for Lambda version (or alias) deployment, but as per the current plan, we will not be automating the API deployment. It will be done manually as per the roadmap.

1. Create one nodejs lambda function getOrders .

2. Generate two versions of the function with some changes in the JSON response.

Image title

3. Create a test event to test the lambda. As I have a plan to create a LAMBDA_PROXY type integration in API Gateway, I select the API Gateway AWS Proxy template. The test event JSON request is given below.

{
  "body": "{\"test\":\"body\"}",
  "resource": "/dev/v1/orders",
  "requestContext": {
    "resourceId": "123456",
    "apiId": "1234567890",
    "resourcePath": "/dev/v1/orders",
    "httpMethod": "GET",
    "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
    "accountId": "123456789012",
    "identity": {
      "apiKey": null,
      "userArn": null,
      "cognitoAuthenticationType": null,
      "caller": null,
      "userAgent": "Custom User Agent String",
      "user": null,
      "cognitoIdentityPoolId": null,
      "cognitoIdentityId": null,
      "cognitoAuthenticationProvider": null,
      "sourceIp": "127.0.0.1",
      "accountId": null
    },
    "stage": "dev"
  },
  "queryStringParameters": {
    "start":"2015-10-01T00:00:00Z",
    "end":"2015-10-04T00:00:00Z"
  },
  "headers": {
    "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
    "Accept-Language": "en-US,en;.8",
    "CloudFront-Is-Desktop-Viewer": "true",
    "CloudFront-Is-SmartTV-Viewer": "false",
    "CloudFront-Is-Mobile-Viewer": "false",
    "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
    "CloudFront-Viewer-Country": "US",
    "Accept": "text/html,application/xhtml+xml,application/xml;.9,image/webp,*/*;.8",
    "Upgrade-Insecure-Requests": "1",
    "X-Forwarded-Port": "443",
    "Host": "1234567890.execute-api.us-east-2.amazonaws.com",
    "X-Forwarded-Proto": "https",
    "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
    "CloudFront-Is-Tablet-Viewer": "false",
    "Cache-Control": "",
    "User-Agent": "Custom User Agent String",
    "CloudFront-Forwarded-Proto": "https",
    "Accept-Encoding": "gzip, deflate, sdch"
  },
  "pathParameters": {
    "proxy": "path/to/resource"
  },
  "httpMethod": "GET",
  "stageVariables": {
    "v1fn": "getOrders:1",
    "v2fn":"getOrders:2"
  },
  "path": "/path/to/resource"
}

4. Following the minimum changes I did to test the lambda function:

  • Update resource and resourcePath with planned API Gateway resource path ( /dev/v<#>/orders).
  • httpMethod would be GET for this POC.
  • stage would be dev.
  • queryStringParameters are start and end timestamp.
  • I have a plan to create two versions of the API, each of which will point to the corresponding Lambda version in dev environment. For that, I have created two stageVariables ( v1fn and v2fn) with <function name>:<version number> ( getOrders:1 & getOrders:2)

That’s it. I am done with the test event creation. If I execute the event, I can see the getOrders function is returning the proper output.

5. Now, from the Amazon API Gateway menu, create an API with the following path for two API versions. For version 1, it is /v1/orders, and for version 2, it is /v2/orders .

6. The integration request type is LAMBDA_PROXY to pass queryStringParameters seamlessly.

Image title

7. To implement the LAMBDA_PROXY integration type, we need to do the following setup inside the Integration Request view.

Image title

Note: Here, instead of giving lambda function name, I specify ${stageVariables.<stage-variable-name>}to dynamically select a different function version (or alias).

8. The same setup is needed for /v2/orders resource.

9. Now we can test both the APIs from the API Test wizard.

Image title

Note: We have to enter the stage variable value here during the test (e.g. for v2fn it is getOrders:2), otherwise, the API will behave incorrectly.

10. Now deploy the API in dev stage. The API URI for different versions are as below:

  • https://xxxxxxxxxx.execute-api.xxxxxxxxx.amazonaws.com/dev/v1/orders
  • https://xxxxxxxxxx.execute-api.xxxxxxxxx.amazonaws.com/dev/v2/orders

Image title

Where the resources are /dev/v1/orders and /dev/v2/orders respectively.

Note: We have a plan to deploy lambda code using the AWS CodePipeline. As we have a limited number of APIs, we will manually create an API from the Amazon API Gateway console.

Conclusion

The following are common issues that we have addressed from this implementation.

Issues

How we address

No isolation. If we have a bug in v1 code that can be exploited, all our instances are vulnerable.

There are separate codes for each of the Lambda functions and as it is a functional programming approach, there is no common code between the versions.

Development limitations. We need to support the whole code base, making sure "v1" and "v2" live nicely together. Consider a situation when some dependency is used in both "v1" and "v2" but require specific different versions.

Both v1 and v2 Lambda function codes and their corresponding dependencies are mutually exclusive, so there would be no conflict.

Technology lock-in. It is either impossible or very hard to have "v1" in C# and "v2" in Python.

It may not be possible using Lambda implementation because there is 1:1 mapping between the Lambda function and the programming language.

Capacity planning and monitoring. It is hard to understand how much resources are consumed by "v1" calls vs. "v2."

We can monitor based on the complete and regular expression-based resource path.

Domain name-based and API name-based approaches can also be a possible solution, but as Amazon offers us so much flexibility, we are ardent to implement the versioning with its deepest component and can maintain the traditional flavor.

API AWS

Opinions expressed by DZone contributors are their own.

Related

  • Unlocking the Benefits of a Private API in AWS API Gateway
  • Building a Scalable ML Pipeline and API in AWS
  • Container Checkpointing in Kubernetes With a Custom API
  • Serverless NLP: Implementing Sentiment Analysis Using Serverless Technologies

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!