Proof of concept

How to Migrate Your REST API to the New HTTP API in AWS

How to Migrate Your REST API to the New HTTP API in AWS

Last week, the Twitterverse was buzzing about HTTP APIs becoming generally available in AWS. For some, it was a much-anticipated announcement, but others were left scratching their heads wondering, “What is an HTTP API?”

Boiling it down to the core, HTTP APIs are simple, lightweight API gateways that proxy to various AWS services. Their simplicity offers faster development throughput, cheaper service costs, and faster execution times.

So who wants to build one?

Getting Set Up

There is already a plethora of walkthroughs, guides, and articles on how to build an HTTP API from scratch. So we aren’t going to do that today. We are going to cover the much likelier scenario you have: how to move existing REST API code to HTTP.

To keep it easy, I’ve provided a repo on GitHub that has a REST API and the equivalent in HTTP. The API offers the basic create/read/update/delete functionality of an “item” object.

The API takes advantage of Open API Spec 3.0 (OAS3.0), SAM template, and Lambda functions. If you aren’t using OAS3.0 already, you should. I wrote about it at length last week and highly recommend getting familiar with it.

So do a once-over of the README, make sure you have the prereqs installed, and pull it down.

Change #1: Lambda Response

Did you know there are two versions of lambda payloads? REST uses v1.0 by default, and HTTP uses v2.0 by default. If you want, you could keep your lambdas the way they are and tell the API to use payload v1, but we’re trying to be cutting edge here. Plus it’s actually a lot nicer.

In a quick game of “Spot the Differences,” we can see the following changes:

  • REST is returning CORS headers and HTTP is not.
  • HTTP is doing request validation, whereas REST is not.
  • REST is stringifying the body and HTTP is not.
  • HTTP only returns the entity on success. REST returns the full response object.

We will cover the first two differences later in the article, but we can talk about the last two now. Those differences deal with the version change of the response.

Payload v2 makes some assumptions when you return content from a lambda. It assumes you are returning a status of 200 and that the entity being returned is a JSON object for the response body.

If you need to return an error code, the format is similar to what it was before, but you don’t need to add the CORS headers or stringify the content. While small, that is a really nice change for a developer.

The request event object has changed as well, splitting multi-value headers and query string parameters into JSON objects so you don’t have to parse them yourself.

Change #2: SAM Template

The SAM template is a way to define your serverless application infrastructure as code. You define your resources in JSON or YAML, and let AWS CloudFormation translate the definition to real resources in the cloud on deploy.

Here is an excerpt of our definition from our old REST API to our new HTTP API:

We can see the following differences between the two definitions:

  • REST adds the CORS definition. HTTP does not.
  • REST uses AWS X-Ray tracing (TracingEnabled: true). HTTP does not
  • REST uses the AWS::Serverless::API resource type. HTTP uses AWS::Serverless::HttpApi.
  • REST uses the Api event type for lambda. HTTP uses the HttpApi event type.

With REST APIs, you must define your CORS configuration in the template file. You have the ability to configure it globally for the API or down at an individual lambda level. For HTTP, this definition moves over to the Open API Specification — we’ll get there soon.

As of the writing of this article, HTTP APIs do not support AWS X-Ray at the gateway level. Your lambdas can still be instrumented with it, but the trace doesn’t start at the gateway level anymore. That’s likely to change in the not-so-distant future.

As for the resource types, that one kind of makes sense. We’re building different types of resources, so we need to change the type in the definition.

Change #3: Open API Specification

As mentioned earlier, if you aren’t defining your APIs with OAS3.0, you really should be. It provides a multitude of benefits and maintains a separation of concerns between your definition files.

Let’s peek at the difference between the REST and HTTP specs:

This is where the majority of our changes come into play. AWS has a multitude of extensions to Open API that drive the behavior in the cloud once deployed. The biggest discrepancy between REST and HTTP APIs is which extensions they support:

  • REST supports request and response validation. HTTP does not.
  • HTTP supports CORS definitions. REST does not.

While there may be fewer differences here, these are impactful differences. Remember how in our lambda changes, we had to add validation on the request body? With REST, the validators sit on top of API Gateway and do not run your lambda code unless everything matches the schema.

Request and response validation are not currently supported in HTTP APIs.

This means that you have to go back and add the simple validation code to your lambda functions to make sure you aren’t getting malicious data. It’s not a difficult task, but it is a little tedious.

Since CORS is defined in the OAS3.0 spec, the HTTP API is able to add the necessary headers for you in your lambda responses. So at least you don’t have to worry about adding those in while you’re refactoring.

Is Migrating Worth It?

The answer to this question is on a case-by-case basis. If you depend on the request validation provided by REST, then you’re probably better off waiting until they add support for it.

If you are just using API Gateway to do basic proxying to your various AWS services, then by all means, take the plunge. AWS released a blog post showing the cost difference between the two gateways. There is a significant cost benefit to switching over that greatly outweighs the cost of a refactor.

Photo from AWS: Cost difference between REST and HTTP APIs. Photo from AWS: Cost difference between REST and HTTP APIs.

Perhaps the biggest feature difference that I didn’t touch on in this article is authentication. If your application uses OIDC or OAuth2.0, you’re going to get support for this right out of the box. That is not something you get with a REST API.

However, if your application depends on a custom Lambda Authorizer, then you might want to wait a bit because those are not supported at present.

If you’d like a full feature comparison between the two, you can reference this article from AWS.

The Choice Is Yours

I encourage you to poke around my repo on GitHub. Get familiar with the implementation differences between the two types of APIs. For side projects, it feels like a no-brainer to build with HTTP APIs. For existing production code that already makes heavy use of request validation and lambda authorizers, maybe wait a little bit.

Ultimately, it is your decision to make. Do the monthly cost savings outweigh the cost of a refactor? Should you wait and see what comes out in the near future?

I do know for sure that knowledge is power. So learn how to build the HTTP APIs. Develop a migration strategy. You will not regret learning something new.

Have fun out there and learn lots. Thanks for reading!

Share on:
comments powered by Disqus

Join the Ready, Set, Cloud! Newsletter

Stay up to date with the latest posts, get the thought of the week, and keep in touch! Subscribe to our weekly newsletter for all these sweet deets.