Skip to content

Jesses Software Engineering Blog

Jan 15

Jesse

Serverless ReactJS with AWS S3

Serverless computing compliments the microservice architecture very well. Instead of provisioning and monitoring a fleet of servers for all the various services, simply use the serverless architecture, only pay for what is used, and don’t spend dev time on maintaining and monitoring infrastructure. Also, by serverless’s cloud based nature and consumption use pricing, serverless architectures are designed to scale out horizontally, expanding to meet resource demand, although there are some caveats to this with some services such as AWS Lambda.

Serverless Stack

Serverless is a managed function, or infrastructure, that lives in the cloud. That means the developer is not responsible for configuring, maintaining, or even monitoring the server where the code is ran from. Serverless computing is typically charged by how much an app consumes, i.e. resources required, vs. a traditional server which is charged by the hour. The benefits of such a model are not only lower overhead, in terms of labor, but also lower cost, at least for low resource intensive processes.

AWS offers a variety of serverless services for architecting web applications. An HTTP request would be routed through AWS S3, the simple object storage, that hosts the static web files. Ajax requests sent to API Gateway which is a tool for setting up a REST API, typically a proxy for AWS Lambda where the “server side” code is actually run. DynamoDB offers the database, and CloudFront can be used as a CDN. The request lifecycle in a serverless web application stack will typically look like:

CloudFront -> S3 -> API Gateway -> Lambda -> DynamoDB 

Each one of these services uses the pay per consumption model, with most offering a free tier for low usage. The cost of running a serverless stack, on small resource consumption, is typically far lower then running machines and paying per hour.

Facebook Incubator ReactJS

Developing with the Facebook Incubator ReactJS create-react-app tool is straightforward, offering rapid development and deployment bundles perfect for serverless environments. When running an app in S3 all files must be compiled prior to deployment, which limits the build tool options. I like the Facebook Incubator ReactJS tool because it is typically all that is needed, but also integrates with tools such as Webpack and Grunt for more complex builds.

The ReactJS app will work the same way as if you were deploying to server, with the exception that all the tasks need to be ran prior to deployment. I have put together a sample project which demonstrates how to configure the router for serverless hosting. There is also an example of an Ajax call for talking with API Gateway.

To get started, simply create the app

create-react-app serverless-reactjs

Run a dev server locally

cd serverless-reactjs
npm start

Bundle for deployment

npm run build

And deploy to a S3 bucket

aws s3 sync build/ s3://serverless-reactjs-bucket

One important caveat here, by using this architecture you sacrifice isomorphic rendering, due to requiring the entire JS package to be loaded prior to the app loading. If this becomes an issue with larger applications, some creative engineering will need to be applied.

AWS S3 Hosting

As I’ve written about before AWS S3 is great for hosting static sites. Once the ReactJS app is ready for prime time, simply upload it to a S3 bucket that has website hosting enabled. You’ll need to set both the index and error documents to the root file, i.e. index.html. This will require the app requests to always be routed through the index file and hit the router.

A custom bucket policy will also need to be set:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::serverless-reactjs-bucket/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": [
            "63.243.124.182"
          ]
        }
      }
    }
  ]
}

The Condition clause is optional if the bucket needs to be restricted by IP address or range i.e. for a staging environment.

Conclusion

Using the Facebook Incubator ReactJS create-react-app tool compliments a serverless AWS S3 architecture very well. It allows for easy local development, and static builds that can be deployed to a static serverless environment.

Blog Powered By Wordpress