How to Build, Launch, and Host an HTTP API on AWS

How to Build, Launch, and Host an HTTP API on AWS

Posted in

Heroku recently announced the closure of their free tier, citing fraud and abuse as reasons for closing their popular web app environment. This is sad news for API developers looking to learn or experiment without paying exorbitant fees.

This has led to a mad scramble to find new alternatives for free API hosting. AWS is a popular suggestion for those looking for a Heroku alternative. AWS has already been a popular API solution for a number of years, thanks to its API gateway and usefulness for managing microservices.

AWS offers a free tier for up to one million API calls and 750,000 minutes of connectivity for HTTP requests. That’s more than enough to learn and experiment with or try out a new API still in production mode.

AWS has a lot going for it, even among paid API solutions. It has all the features you could want from an API management environment, from API monitoring to logging to throttling to API lifecycle management, making it an ideal learning environment while still being robust enough for fully-functional HTTP APIs.

Below, we’ll show you how to get started with HTTP APIs on AWS so you can try it out and see for yourself. Whether you’re new to HTTP APIs, looking for a Heroku alternative, or just want to investigate all the buzz about hosting APIs on AWS, this guide will tell you everything you need to know!

Compete Guide to HTTP APIs on AWS

Develop Your API

The first step in deploying your API is developing an HTTP API in AWS. In AWS, an HTTP API must feature at least one route, integration, stage, and deployment.

Create a Lambda Function

We will start by creating a Lambda function, which is Amazon’s serverless solution. We’re going to connect the function to our HTTP API in a few steps.

If you don’t have an AWS account, you’ll need to create one, but it only takes a moment.

Start by selecting the orange Create function button on the top-right corner of the screen.

On the next screen, choose Author from scratch. Then name your function and select the most recent version of Python from the Runtime pull-down menu. We’ve called our function Test and are using Python 3.9.

Finally, click Create function in the bottom-right corner.

Create an AWS HTTP API Using AWS Management Console

Now we’re going to create an HTTP API. Then we will add some endpoints, known as integrations.

In AWS API Gateway, click the orange Create API button in the top-right corner.

Find the HTTP API frame and select the orange Build button.

Next, you’re going to add an integration, which defines what type of backend interaction the API will expect. Choose Lambda, your AWS Region, and then input the name of the Lambda function you just created.

Now give your API a name and choose Next. We named our API test, as well.

Now you’ll be prompted to create some Routes, which will be your API’s endpoints. We’re going to create two routes: getPerson and createPerson.

Start off by changing the Method to GET. In the first input box called Resource path, input getPerson. Leave Integration target as Test.

Now click Add route.

Change this method to POST. Then call this Resource path createPerson. Let this integration target as Test, as well.

Choose Next and then Create.

Congratulations! You’ve just created your first HTTP API in AWS. It really is that simple. Now we’re going to make it usable.

Edit the Lambda Code

The API you just created will have an Invoke URL. To start, query this Invoke URL using Postman (it’s available for free download if you don’t have it already).

For our example, we’re using https://3q45xzgqw1.execute-api.us-west-2.amazonaws.com//getPerson. In Postman, use the key personID and the value 123, as well.

Now we’re going to edit the Lambda code.

In the Lambda window, start by inputting the following into the Lambda code editor.

import json


def lambda_handler(event, context):
    # TODO implement
    print("This is the event")
    print(event)

In the code editor, choose Deploy.

Next, navigate over to the Monitor tab above the code editor. Select View Logs in Cloudwatch. Find the most recent log.

The resulting JSON will be fairly ugly and unreadable, so let’s make it a bit prettier to better understand what we’re looking at. We’re going to input the returned JSON file into JSON FORMATTER.

Our returned code looks like this:

{
   "version":"2.0",
   "routeKey":"GET /getPerson",
   "rawPath":"/getPerson",
   "rawQueryString":"personID%20=123",
   "headers":{
      "accept":"*/*",
      "accept-encoding":"gzip, deflate, br",
      "cache-control":"no-cache",
      "content-length":"0",
      "host":"3q45xzgqw1.execute-api.us-west-2.amazonaws.com",
      "postman-token":"75d1b655-efc8-4a99-99c8-3a6e634cde7e",
      "user-agent":"PostmanRuntime/7.26.8",
      "x-amzn-trace-id":"Root=1-639cf000-6d8f27d03d8e48d94aec15f5",
      "x-forwarded-for":"72.182.50.7",
      "x-forwarded-port":"443",
      "x-forwarded-proto":"https"
   },
   "queryStringParameters":{
      "personID ":"123"
   },
   "requestContext":{
      "accountId":"794776726292",
      "apiId":"3q45xzgqw1",
      "domainName":"3q45xzgqw1.execute-api.us-west-2.amazonaws.com",
      "domainPrefix":"3q45xzgqw1",
      "http":{
         "method":"GET",
         "path":"/getPerson",
         "protocol":"HTTP/1.1",
         "sourceIp":"72.182.50.7",
         "userAgent":"PostmanRuntime/7.26.8"
      },
      "requestId":"dQpwDgkYPHcEJQg=",
      "routeKey":"GET /getPerson",
      "stage":"$default",
      "time":"16/Dec/2022:22:24:00 +0000",
      "timeEpoch":1671229440136
   },
   "isBase64Encoded":false
}
`

You can see that the path queried was getPerson and the personID is 123.

Next, let’s try out adding some data using /createPerson.

In Postman, switch from the /getPerson to the /createPerson endpoint. Our example endpoint looks like https://3q45xzgqw1.execute-api.us-west-2.amazonaws.com//createPerson.

Switch from the GET method to the POST method, as well.

Now you’re going to send some data. We’re going to create a very simple customer ID for an example.

In Postman, navigate to the Body tab, which will be empty as we haven’t input anything yet. Select the Raw option, as we’re going to send a raw JSON object.

In the body, input:

{
    "firstName": "Jean"
    "lastName": "Shepherd"
    "email": "squaresville@gmail.com" 
}

Then click Send.

Now we’re going to navigate back to the Lambda Cloudwatch log. Refresh the results. You’ll see an entry that reads, “This is the event.” Beneath that, you’ll see a string of raw JSON data.

Once we’ve cleaned up the results, we’ll get:

{
   "version":"2.0",
   "routeKey":"POST /createPerson",
   "rawPath":"/createPerson",
   "rawQueryString":"personid%20=123",
   "headers":{
      "accept":"*/*",
      "accept-encoding":"gzip, deflate, br",
      "cache-control":"no-cache",
      "content-length":"97",
      "content-type":"text/plain",
      "host":"3q45xzgqw1.execute-api.us-west-2.amazonaws.com",
      "postman-token":"2b73ffbd-ebcc-490c-9495-d6ba730dda96",
      "user-agent":"PostmanRuntime/7.26.8",
      "x-amzn-trace-id":"Root=1-63a00e72-200ac216451cabd44ed5dd4e",
      "x-forwarded-for":"136.49.56.92",
      "x-forwarded-port":"443",
      "x-forwarded-proto":"https"
   },
   "queryStringParameters":{
      "personid ":"123"
   },
   "requestContext":{
      "accountId":"794776726292",
      "apiId":"3q45xzgqw1",
      "domainName":"3q45xzgqw1.execute-api.us-west-2.amazonaws.com",
      "domainPrefix":"3q45xzgqw1",
      "http":{
         "method":"POST",
         "path":"/createPerson",
         "protocol":"HTTP/1.1",
         "sourceIp":"136.49.56.92",
         "userAgent":"PostmanRuntime/7.26.8"
      },
      "requestId":"dYcx_g_iPHcEMOA=",
      "routeKey":"POST /createPerson",
      "stage":"$default",
      "time":"19/Dec/2022:07:10:42 +0000",
      "timeEpoch":1671433842909
   },
   "body":"{\r\n    \"firstName\": \"Jean\"\r\n    \"lastName\": \"Shepherd\"\r\n    \"email\": \"squaresville@gmail.com\" \r\n}",
   "isBase64Encoded":false
}

As you can see, this query has added a firstName, lastName, and an email address using an API call. This is the essence of any customer database, all written using only API calls.

Final Thoughts on Building, Launching, and Hosting an HTTP API on AWS

As you can see, there’s not a lot to building an HTTP API using AWS. Don’t let the simplicity fool you, though, as even this barebones tutorial covers a lot of essential API techniques.

In this AWS API tutorial, we learned how to use the AWS API gateway, for starters. That portal alone has a vast library of functionality to explore. It’s no hobbyist toolkit, despite the free tier. We also learned how to create API endpoints using AWS API gateway, where they’re known as Routes. If you dig deeper into the AWS API gateway, you can experiment with adding layers and stages for further routing options.

We even learned a bit about some tangential API-related skills like using Postman and working with tools to prettify your JSON.

Finally, we learned how to create and attach a Lambda function, which is another powerful and popular feature of AWS. These two components alone are some of the main components of hosting an API on AWS, and you can get started with them in a matter of minutes once you know what you’re doing.