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

Sample Website

yarn create vuepress-site

API Gateway and S3 Setup

S3 Bucket:

const bucketWebsite = new s3.Bucket(this, "WebsiteBucket");// This will deploy the sources to the destination bucket
new s3Deploy.BucketDeployment(
this, "deploy-frontend", { sources: [ s3Deploy.Source.asset("../docs/src/.vuepress/dist") ], destinationBucket: bucketWebsite });

API Gateway Rest API:

const api = new apigateway.RestApi(  this,  "ApiGatewayS3Proxy",  {    restApiName: "StaticWebsite",    // The regional endpoint is faster to deploy as it does not create a CloudFront distribution    endpointTypes: [apigateway.EndpointType.REGIONAL],

// We need to configure the supported binary media types so that they are forwarded from S3 through API Gateway to the Browser
binaryMediaTypes: [ "application/javascript", "image/png", "image/jpeg", "application/font-woff2", "application/font-woff", "font/woff", "font/woff2", ], });

API Gateway S3 Integration:

const indexPageIntegration = new apigateway.AwsIntegration({  service: "s3",  integrationHttpMethod: "GET",  path: `${bucket.bucketName}/index.html`,  options: {    credentialsRole: apiGatewayS3ReadRole,    passthroughBehavior: PassthroughBehavior.WHEN_NO_MATCH,    integrationResponses: [    {      statusCode: "200",      responseParameters: {        "method.response.header.Content-Type": "integration.response.header.Content-Type",        "method.response.header.Timestamp":  "integration.response.header.Date"      },    },  ]},});const methodOptions: MethodOptions = { methodResponses: [  { statusCode: '200', responseParameters:   {"method.response.header.Content-Type": true,  "method.response.header.Timestamp": true}},  { statusCode: '400' },  { statusCode: '500' }]};// we add a GET method to the root resource. api.root.addMethod("GET", indexPageIntegration, methodOptions);
const assetsIntegration = new apigateway.AwsIntegration({  service: "s3",  integrationHttpMethod: "GET",  path: `${bucket.bucketName}/assets/{path}`,  options: {    credentialsRole: apiGatewayS3ReadRole,    passthroughBehavior: apigateway.PassthroughBehavior.WHEN_NO_MATCH,    requestParameters: {      "integration.request.path.path": "method.request.path.path"    },    integrationResponses: [    {      statusCode: "200",      responseParameters: {        "method.response.header.Content-Type": "integration.response.header.Content-Type",        "method.response.header.Timestamp": "integration.response.header.Date"      },    },  ]},});const assets = root.addResource("assets");assets.addResource("{path+}")
.addMethod("GET", assetsIntegration, {...methodOptions, requestParameters: {"method.request.path.path": true}});

Evaluation

Pros

  • 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 )

Cons

  • 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.

Summary

--

--

--

Freelance Web Developer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How to start an Open Source project. Building RESO API JS client

What is the Difference between foreach and forelse in Laravel

BEST JAVASCRIPTS LIBRARIES FOR WEB DEVELOPERS

Clean Code Applied to JavaScript (Part 7: Practical Refactoring)

//platform.twitter.com/widgets.js from Twitter https://twitter.com/thehikeexperts

Adding Functionality to React

Five methods to style a React Component

Quick Start Node JS with Debugging

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
Aco Mitevski

Aco Mitevski

Freelance Web Developer

More from Medium

Primary Key Design In AWS DynamoDB

Primary Key Design In AWS DynamoDB

Amazon API Gateway: Securing Endpoints using API Keys

Setting up Serverless Framework with AWS

How to create custom domain API in AWS API Gateway