AWS Mobile Blog

React serverless starter application with one-click AWS deployment and hosting

Serverless applications are more popular every day. Many developers want to implement completely serverless hosted websites that are functionally equivalent to traditional infrastructures. However, with serverless websites, it’s often tricky to deal with registration, sign-in, and MFA flows. It can also be difficult to manage API routing, CORS settings, endpoint authorization, and user authentication. Hooking all of these features together with a hosting solution and global CDN takes extra time for features that are standard for business applications today.

We’ve recently been blogging about building applications with React and using them in conjunction with the Hosting and Streaming AWS Mobile Hub features. Today, we are announcing a couple of additions to this solution set.

First, we’ve enhanced the Cloud Logic functionality in a Mobile Hub project so that new projects launched via Import can include a custom AWS Lambda function. The import can also configure more settings such as CORS for Amazon API Gateway or Lambda environment variables.

Second we are releasing a ReactJS starter project on GitHub to demonstrate these capabilities. The sample can be run with a single click, using the new Deploy from GitHub button capabilities of Mobile Hub. After it is deployed, you can run the sample locally with a webpack server. You can also deploy it as an Amazon S3 hosted static site with an Amazon CloudFront origin. The sample is optimized for mobile devices, which enables you to view the app from your phone or desktop browser. You can register users in the system and log user in with SMS-based MFA. After they are signed in, users can insert sample data for “BBQ Restaurants” and view all restaurants in the system. They can then navigate to see everything on the menu and place an order. The sample also demonstrates using forgotten password workflows.

In the sample, the import functionality automatically configures the following:

  • Amazon Cognito User Pools and Federated Identities
  • Amazon API Gateway, AWS Lambda, and Amazon DynamoDB
  • Cross-origin resource sharing (CORS) for the API
  • IAM roles and policy for the Lambda execution role
  • IAM roles and policy for the user roles that access API routes after authentication

You can find the sample demonstrating this functionality here. The repository describes the steps to get the sample running, and describes how to use portions of the sample in your own application and customizations. In this blog post, we dive into a few details.

Prerequisites

To get the sample running quickly you need:

Installation

Clone the GitHub repository and use the Deploy to Mobile Hub button on the page.

After the deployment is complete, click Hosting and Streaming in the Mobile Hub console. At the bottom of the page, download the aws-exports.js file into the ./aws-mobile-react-sample/client/src/configuration folder of your cloned repo.

Use the following commands to run the application:


npm install
npm start

Walkthrough of the application

After the application is running you will see a page with a Login or SignUp Now button. Click SignUp Now to register a new user in the system.

An SMS confirmation code is sent to the phone number you provide. You must provide the phone number to complete the registration process. The confirmation code redirects you to the home screen, where you enter the username and password and then click Login.

You will recieve another confirmation code. This is the MFA code for logging in the user. Enter the code in the screen to complete the login process.

Now that you’re in the application, click Insert Restaurants to load data into the system. Behind the scenes, this invokes Amazon API Gateway, using the valid user credentials from Amazon Cognito. The API is configured to route the request to AWS Lambda, which is running Express using AWS Serverless Express. A route is configured to initialize data, which inserts sample data into Amazon DynamoDB.

Next click List Restaurants. The restaurants that were added into DynamoDB appear

Click any of the restaurants to see a menu. Place an order by clicking the Order button next to an item.

To see the current order, click Orders in the navigation bar. Two records display immediately and two other records display momentarily. This is to demonstrate persisting data in local storage for rendering versus returning a response from a network call.

You can also package and deploy the app by running:

npm run build

The build uses webpack to produce a bundle that can be uploaded to the S3 bucket created by the import. The output will be in ./aws-mobile-react-sample/client/build.

You can use the AWS CLI to upload the contents of this directory to the bucket. This process is described on GitHub. You can also use the Manage Files function in the Hosting and Streaming page of the Mobile Hub console.

After you upload the contents of the build directory, click either View from S3 or View from CloudFront to see your deployed erverless website.

Customization

The GitHub repository covers some advanced scenarios for modifying this sample or using pieces of it in your own React application. Some of these scenarios are as follows:

  • Using the registration and login components with Amazon Cognito for your application.
  • Using the REST client to make signed, authenticated requests to Amazon API Gatway.
  • Using the REST client to make unauthenticated requests to Amazon API Gateway or generic HTTP resources.
  • Modifying the Express routes in AWS Lambda to perform different operations against Amazon DynamoDB, and calling these routes from the client application.

You can also modify the import process to fit your needs and include this in your own GitHub repository with a one-click button. If you open the ./aws-mobile-react-sample/backend/import_mobilehub directory in the repository and unzip react-sample.zip, you will find the following:

  • lambda-archive.zip
  • mobile-hub-project.yml

The lambda-archive.zip is the pre-built Lambda function, which you can use on import. This must follow the Lambda deployment process described in the AWS Lambda Developer Guide. We also include these steps in the Advanced section of the repository.

If you edit mobile-hub-project.yml you’ll notice some other interesting things that are now available for you to configure with project imports.

UPLOADS

The uploads section determines the custom AWS Lambda function that you can provide during an import. In our sample we use lambda-archive.zip, which was created from the files in the ./aws-mobile-react-sample/backend/lambda directory. The YAML section should also specify the target bucket as follows:

uploads:
  - !com.amazonaws.mobilehub.v0.Upload
    fileName: lambda-archive.zip
    targetS3Bucket: deployments

CLOUD LOGIC

In the same YAML file, you’ll notice the cloudlogic section. This contains everything you need to configure a custom AWS Lambda function and related settings as well as setting up your Amazon API Gatway API. You can configure things such as enabling CORS on the API or only allowing authenticated and authorized users access to invoke the API. This sample YAML demonstrates using Amazon Cognito to access the Amazon API Gateway API and configuring environment variables for your custom AWS Lambda function. You’ll also see controls such as runtime for your NodeJS version and handler which is the name of the file entry point for your code.

You can use ___DYNAMIC_PREFIX___-statictext in the enviornment variables configuration. This is beneficial for resources such as Amazon DynamoDB tables, which are generated at the time of import, Mobile Hub performs the appropriate substitutions after resource creation.

The YAML section should look like the following:

features:
  cloudlogic: !com.amazonaws.mobilehub.v0.CloudLogic
    components:
      ReactSample: !com.amazonaws.mobilehub.v0.API
        attributes:
          name: ReactSample
          requires-signin: true
        paths:
          /items: !com.amazonaws.mobilehub.v0.Function
            name: ReactSample
            codeFilename: uploads/lambda-archive.zip
            handler: lambda.handler
            enableCORS: true
            runtime: nodejs6.10
            environment:
              MENU_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_menu_item
              ORDERS_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_orders
              RESTAURANTS_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_restaurants
          "/items/{proxy+}": !com.amazonaws.mobilehub.v0.Function
            name: ReactSample
            codeFilename: uploads/lambda-archive.zip
            handler: lambda.handler
            enableCORS: true
            runtime: nodejs6.10
            environment:
              MENU_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_menu_item
              ORDERS_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_orders
              RESTAURANTS_TABLE_NAME: ___DYNAMIC_PREFIX___-bbq_restaurants

 

The Mobile Hub import process also prepopulates some Environment Variables in the Lambda configuration:

  • MOBILE_HUB_DYNAMIC_PREFIX
  • MOBILE_HUB_PROJECT_ID
  • MOBILE_HUB_PROJECT_NAME
  • MOBILE_HUB_PROJECT_REGION

As a usage example, you could re-write the Lambda code in the starter application to reference these like so:


const MENU_TABLE_NAME = `${process.env.MOBILE_HUB_DYNAMIC_PREFIX}-bbq_menu_item`;
const ORDERS_TABLE_NAME = `${process.env.MOBILE_HUB_DYNAMIC_PREFIX}-bbq_orders`;
const RESTAURANTS_TABLE_NAME = `${process.env.MOBILE_HUB_DYNAMIC_PREFIX}-bbq_restaurants `;

You could also use these prepopulated variables for other utility purposes.

Wrapping up

We’re excited to bring you these capabilities. We hope that they accelerate your next serverless website or React project using AWS. Let us know in the GitHub issues section of the repository if you have any feedback or requests.