How to host a serverless static website on AWS with API Gateway

By Aco Mitevski

Now comes the interesting part. I am using cdk to setup an S3 Bucket that holds the static website and a Rest API in API Gateway with the according resources that will get the right files through the S3 Proxy integration. To keep it readable the code samples are not complete. But you can find the full code at github.

S3 Bucket:

This part is straight forward. We create a new bucket and deploy our static assets. The cool thing about the BucketDeployment Construct is that it already sets the right Content-Type for us in S3.

API Gateway Rest API:

The Rest API is mostly standard. The most important part here is to define the supported Binary Media Types so that we can forward them from S3 to the Browser.

API Gateway S3 Integration:

In the S3 integration we configure through responseParameters which headers should be forwarded from S3 to the browser. The code below maps all requests to / to the index.html int the S3 Bucket.

We can also configure catchall or proxy+ routes is the name in API Gateway. In our example this is usable for the assets folder. Important part is to define the requestParameters to forward the path param to S3.

Evaluation

  • Faster deployment (without CloudFront)
  • Can be deployed without any resources in us-east-1 (without CloudFront)
  • very flexible and lots of features (Throttling, API Keys, Custom Domain …)
  • same API Gateway can be used for Backend routes
  • Authentication can be added easily with API Gateway Authorizers ( Cognito Integration, IAM or Custom Authorizer )
  • Compared to CloudFront API Gateway can get very expensive if you receive a lot of requests (millions), so handle with care
  • The routing configuration can get quite big depending how your static site is structured.

We managed to host a serverless static website in AWS without involving CloudFront. For high traffic websites this might not be very useful. But with special requirements it makes sense.

In a production app you will probably add a custom domain and authentication.

I used cdk to define the API but you can use any other supported method (OpenAPI, Smithy).