How-to: Integrate a Legacy API with AWS using API Gateway

Abdul R. Wahab
6 min readDec 6, 2021


When you have numerous mobile and web applications that are all backed by many hundreds of HTTP endpoints, you need a method to efficiently integrate, deploy, retire, throttle, and secure those microservices/APIs.

Each microservice does one specific thing, and serves a particular purpose in the grand context of an application. And every complex application is composed of many microservices that are (or can tend to be) developed in unique ways (i.e. programming frameworks/languages, deployment environments, containers, etc.).

Some of them might even be Vendor APIs, rendering them totally outside of the management and governance of a company that is developing a particular application as whole.

So.. making changes to the API itself, in order to be able to better consume the API can be a lot harder.

Say Hi to API Gateway Proxy Integration! 🙋‍♂️

Amazon API Gateway offered by AWS helps to build and expose a coherent API format for all microservices that build up an application.

You can (also) use API Gateway for proxying, and be able to modify and enhance any incoming API requests via caching, load balancing, as well as providing a general security layer (gateway/gatekeeper) for your APIs.

API Gateway is also managed serverlessly, so that benefits you by not having to be concerned with directly scaling in response to request volumes. AWS can handle that for you, with a flat per request rate of $1.50/1 million API requests.

I will now begin to dive into the meat of the topic: Why and how to use API Gateway Proxy integration for Legacy APIs.

How do API Gateway Integrations work? 🤔

An API Integration is the type of action (aka, method call/verb) that is made by the API Gateway, in order to respond to a particular API call. The integration is triggered after the incoming API request is validated and authorized.

Amazon’s API Gateway supports these types of API Integrations:

  1. HTTP & HTTP Proxy Integration: This one is the simplest type of integration, API Gateway just forwards the incoming requests to an HTTP server. Offers two modes: Proxy (HTTP_PROXY) and Non-Proxy (HTTP). It can be used for integrating existing APIs within AWS, and also Legacy APIs that exist outside of AWS (aka, housed on-prem servers).
  2. Lambda Integration: Uses AWS_PROXY. In this mode, a Lambda function is invoked in order to manage the request. The full request is forwarded over to a Lambda via a JSON object.
  3. Other AWS Service (AWS): This integration enables API requests to be forwarded to other AWS services (ex: SQS, Lambda, Glue, Kinesis, etc.) after they are transformed to adhere to AWS Service API specifications. You can also specify IAM Roles that should execute the request to the Service APIs.
  4. MOCK Integration: This one returns predefined static responses, or responses to which very little logic is built using Velocity Templates. Reference to Mock Integration (link).

Real-World Use Cases

A typical, and widely-common API Gateway use case in which most of the previously mentioned integrations are actually leveraged is the Migration of a legacy application from an already-existing monolithic infrastructure setup, to a more modern microservice-oriented, modularized application.

In this use case, we usually have numerous APIs that are still hosted on the monolithic service infrastructure, and some APIs that have already been migrated to AWS Lambda (via the AWS_PROXY integration), and/or AWS EKS behind some sort of network or application load balancer.

API Gateway can expose a single-endpoint, which can be mapped to a FQDN (Fully Qualified Domain Name) of our choosing, using the Custom Domain API Gateway feature.

Let’s Proxy our API! 👷‍♂️

I will now walk us through on integrating with the legacy monolthic portion of our application being migrated to AWS.

For this tutorial’s simplicity, I am using the Bored API, which is publicly-reachable.

But you are free to follow this tutorial with any of the publicly-reachable APIs listed here. 🙂

Step 1) Create a New API in the AWS API Gateway Console

Select Build on the REST API (the non-private one, on the bottom left).

Once you’ve clicked Build, you will be presented with a setup screen like below.

Select the New API radio button, fill out the API name* and Description fields.

Once you’ve filled out the details above, click on Create API to wrap up the creation setup.

You should see a screen like this:

Next, we will integrate our Legacy API.

Step 2) Integration with the Legacy API

The easiest thing we can do is to set up a plain proxy using the HTTP_PROXY integration mode.

For this tutorial, I will use HTTP_PROXY as an integration mode targeting the Bored API linked here:

Click on the Actions dropdown arrow, and select Create Resource.

For Configure as proxy resource, check that option. And you can leave Resource Name* and Resource Path* as proxy, and {proxy+}, respectively.

Once you are done filling out the Resource configurations, click on Create Resource on the bottom left.

After creating the resource, your screen should look like this:

You will notice in the left-side panel under Resources /{proxy+}.

Select it, and click the dropdown arrow on Resource Actions to create a Method of type ANY with these settings:

The Endpoint URL I am using is:{proxy}

Click Save.

Once you have saved the Method, your screen will look like this:

Now that we have created our API Gateway, Resource, and Method, we will deploy our API to make it reachable.

Step 3) Deploying & Testing our API

Click on the Actions dropdown arrow, and pick Deploy API.

Clicking Deploy API will present to you a window like this.

For Deployment stage, select [New Stage] from the dropdown, and enter anything you prefer for the remaining fields. I just like being descriptive, so I added detailed descriptions.

Once all of that is filled out, click Deploy.

After the Deployment has completed, you will notice your new API endpoint in the Stages section (listed next to Invoke URL).

I will do a test call via my Linux terminal using cURL commands:

And here is the method call being completed:

"activity": "Learn calligraphy",
"type": "education",
"participants": 1,
"price": 0.1,
"link": "",
"key": "4565537",
"accessibility": 0.1

And now we have a fully serverless proxy for our Legacy API.

Thank you for following along! 🙂

In the next part of this tutorial, I will walk us through on how to create a custom domain name for our API.

Custom domains will make it easier for our various consumers (applications) to call our newly-integrated API.

I’d love to hear your thoughts, so please let me know what you think.

Cheers! 🤝 👋

Want to learn more about AWS Cloud?

Check out my series listed below! 🙂

AWS Cloud:👇

AWS Cloud

27 stories



Implementing a Data Mesh Architecture with AWS Redshift Spectrum and Lake Formation

4 min read

May 7

Using Vault Agent Caching to authenticate to Amazon RDS

3 min read

Apr 21

Different ways to migrate Terraform State

4 min read

May 4

Python ThreadPoolExecutor: Use Cases for Parallel Processing

6 min read

Apr 29

Authenticating to AWS Redshift using Ephemeral Credentials

3 min read

Apr 29

How-to: Create a Custom Terraform Module

4 min read

Apr 21

How-to: Decide whether to use TypeScript or JavaScript

3 min read

Apr 20

How-to: Handle Concurrency & Parallelism in Python

3 min read

Apr 20

Semantic Versioning & Release: A Deep Dive

3 min read

Apr 19

How-to: Create a Data Lake using AWS Lake Formation

9 min read

Dec 4, 2022

Abdul R. Wahab

Tech guy. I like building cool software, & also leading others in building cool things. All views shared are my own.