Creating an API with AWS Lambda, AWS API Gateway, and RapidAPI

Lately, I’ve been really interested in serverless technology and the various use cases that would be ideal to use it for. I had a project come up that was going to be a perfect use case for it, so I decided to dive right in and learn all about AWS Lambda! Unfortunately, as I was getting started with the project, I couldn’t find very many good, up to date, resources around exactly how to create an API using AWS Lambda and API Gateway. After learning the ins and outs of how to accomplish this, I decided to write my own blog post for others who are trying to learn too.

Creating the Lambda Function

imgur
imgur

The most basic version of an API would be an API that simply allows you to call the API and return a 200 response with a body of “hello from AWS Lambda!” To achieve this functionality with a Lambda function, here’s the code you’ll input to do this:

exports.handler = (event, context, callback) => {
var responseBody = {
message: "hello from AWS Lambda!"
};
callback(null, {
statusCode: 200,
headers: { "x-custom-header" : "my custom header value" },
body: JSON.stringify(responseBody)
});
};

This is pretty straightforward code where you’re using the callback parameter result of a successful function execution. That includes a status code of 200 along with headers and a body. All of this information will be sent as a response to the code that called your API in the first place.

Parsing Params and Headers in Lambda Function

let parameter = event['queryStringParameters']['name_of_parameter'];
let header = event['headers']['name_of_header'];

// OR

let paramter2 = event.queryStringParameters.name_of_parameter_one;
let header2 = event.headers.name_of_header_one;

Creating the API Gateway

Create a new API
Create a new API

Once you’ve created your API, you need to start defining the spec of the API.

Proxy API vs. Defined API

Proxy API

Proxy resource definition page
Proxy resource definition page

This means that your API gateway will route every single HTTP requests that include your base URL to your Lambda integration, then your Lambda integration will do the heavy lifting to process the different types of requests.

Let’s say your base URL is https://api.myapi.com/ and then you have a GET request to https://api.myapi.com/hello and POST request https://api.myapi.com/goodbye. Although these are both different HTTP methods to different resources, when using the proxy resource integration your lambda function will be executed for both of these requests.

The upside to this setup is that you are able to route multiples paths to the same Lambda integration. If you already have a codebase setup in this way it will be an easy way to get started with serverless technology without having to completely refactor your code.

There are quite a few downsides that you should know though. Some of these downsides include: The code for your Lambda function will be large as you’re having to handle all of the logic paths in the code. You’re paying to run the routing in the Lambda function instead of allowing the API gateway to do it for you. You’re not utilizing a lot of the features of the API gateway like API documentation.

Parsing different endpoints within the same Lambda function

If you do end up using the proxy integration feature, then you’ll need to do your own logic to handle each endpoint in a different manner. You will access the API request path information in a similar way to how you accessed the header and parameter information. The code to do this is:

let nameOfPath = event['path'];

// OR

let nameOfPath2 = event.path;

Should you go with this option, you will likely want to use if statements to handle each different path available and have a catch-all else statement to handle any non-defined API endpoints. This could look something like this:

exports.handler = (event, context, callback) => {
if (event.path === '/hello') {
callback(null, {
statusCode: 200,
body: JSON.stringify({message: 'hello'})
});
} else if (event.path === '/goodbye') {
callback(null, {
statusCode: 200,
body: JSON.stringify({message: 'goodbye'})
});
} else {
callback(null, {
statusCode: 404
});
}
}

Fully Defined API

I decided to add in a new resource called “/my-resource”

Create Resource
Create Resource

When defining the resource, you’ll just need to input the resource name and resource path. Since we’re not using the proxy resource, you can leave that unchecked.

Define Resource
Define Resource

After you’ve created your resource, you’ll want to create a method for that resource.

Create Method
Create Method

I’ve opted to use a GET request to my /my-resource endpoint.

When creating a new method, be sure that you use the Lambda Proxy integration. This allows the parameters and headers to be sent to your Lambda function. You’ll also want to select the Lambda function you want to activate when this endpoint is called.

API Resource Setup
API Resource Setup

Once you’ve defined all of your API endpoints, you need to deploy your API.

Deploy API
Deploy API

When Deploying, you’ll have to create a new stage to deploy your API. I’ve decided to name mine Staging because I am still in the development phase, but you can name your API stage whatever you like.

Select stage of deployment
Select stage of deployment

After deploying your API, you should now see an “Invoke URL” This is the URL that you will use to call your API. The format to call the API will be your Invoke URL followed by your resource name: https://qa397wgn73.execute-api.us-west-1.amazonaws.com/Staging/my-resource

Making your First Request

Example Request to the API using Postman
Example Request to the API using Postman

Adding API Key Authentication with RapidAPI

A great tool to do user management, API key generation, analytics, and billing for you is a tool called RapidAPI.

To start, you’ll need to be logged in to RapidAPI. Once you’ve created an account, you can head over to our documentation on Adding and Managing Your API. This will detail exactly how you’ll want to add your API to the RapidAPI marketplace. The basic steps are:

  1. Create & name your API
  2. Add the base URL for your API
  • This is going to be the Invoke URL from your AWS API Gateway.
  1. Document all of the endpoints your API has available
  • This is going to be all of the resources and methods you’ve defined for your API.

Now that your API has been documented for consumption through RapidAPI, you’re ready to set up authentication.

The beauty of RapidAPI is that we handle all user management and billing for you! That means as long as you set up a pricing plan and API access according to how you want to allow developers to access the API, then all you have to do is authenticate if a request is coming from RapidAPI or not in your code. Since we do all of the authentication before an API request is made to your systems, then you can allow any request coming from the RapidAPI systems to successfully call your API.

The easiest way to do this is to use our secret hidden header called “X-Mashape-Proxy-Secret” which is a unique secret key sent with every API request to your systems. The developers using your API will never see this key and the key is unique to every API. To find your X-Mashape-Proxy-Secret, go to your APIs network settings page on the Mashape portal.

To use this key to authenticate requests as coming from RapidAPI, you’ll just want to do a quick check right when a request comes in to see if the X-Mashape-Proxy header is present and matches your unique key. Here’s the code to do that:

exports.handler = (event, context, callback) => {
if(event['headers']['X-Mashape-Proxy-Secret'] != '*******************') {
callback(null, {
statusCode: 401,
body: JSON.stringify({message: 'Unauthorized'})
});
} else {
// You API logic goes here
let name = event['queryStringParameters']['name'];

var responseBody = {
message: "hello " + name + "!"
};
callback(null, {
statusCode: 200,
body: JSON.stringify(responseBody)
});
}
}

On top of easily adding user authentication and API key management, you also get the benefit of automatically exposing your API to our large developer community that would be thrilled to use your awesome API! If you get your API up and running on the marketplace, we would love to hear all about it! Feel free to email us at community@rapidapi.com to let us know about any APIs you’ve added on RapidAPI or projects you’re working on that use an API through RapidAPI.

Current: Head of Sales Engineering RapidAPI. Former: Head of Developer Relations RapidAPI, Founder of HackCU. Part-time adventurer, full-time hooligan

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store