|
| 1 | + |
| 2 | +## Amplify CLI React Tutorial |
| 3 | +This tutorial will walk you through using the AWS Amplify CLI with a React application. A similar process could be used with a React Native application (you would omit hosting) or alternative JavaScript frameworks. |
| 4 | + |
| 5 | + |
| 6 | +# Installation |
| 7 | +- An AWS Account and credentials are necessary. See [LINK](). |
| 8 | +- Ensure you have NodeJS installed |
| 9 | + - Examples below use `yarn` but `npm` works as well. |
| 10 | +- Download [LINK](https://amplify-cli-beta-3dd89264-8c7c-11e8-9eb6-529269fb1459.s3.amazonaws.com/amplify-cli-0.1.0.tgz?AWSAccessKeyId=AKIAIFBGMKZSDB7FRP7A&Signature=l8ieJ9wqXDJN8TJ02D63Taxmgjo%3D&Expires=1533366622) |
| 11 | +- Navigate into the unpacked directory and run `npm run setup-dev` |
| 12 | +- Ensure you have [Create React App](https://github.com/facebook/create-react-app) installed and create a new project: |
| 13 | +``` |
| 14 | +yarn create-react-app -g |
| 15 | +create-react-app myapp |
| 16 | +cd myapp |
| 17 | +``` |
| 18 | + |
| 19 | +# Familiarizing yourself with the CLI |
| 20 | +To get started, inside the new directory initialize your project: |
| 21 | +`amplify init` |
| 22 | + |
| 23 | +After answering a few questions |
| 24 | + |
| 25 | +`amplify help` can be used at any time to see the overall command structure, and `amplify help <category>` to see actions for a specific category. |
| 26 | + |
| 27 | +The Amplify CLI uses Amazon CloudFormation under the covers, and you can add/modify configurations locally before pushing them for execution in your account. To see the status of the deployment at any time type `amplify status`. |
| 28 | + |
| 29 | +# Publish your web app |
| 30 | + |
| 31 | +Without making any changes to your React application add in web hosting: |
| 32 | +`amplify add hosting`. |
| 33 | + |
| 34 | +You'll notice some questions are asked such as the bucket name or application files. You can use the defaults for most of these by pressing **Enter**. |
| 35 | + |
| 36 | +**Note**: Adding or removing category features has an order alias for convenience. Typing `amplify hosting add` would also work. |
| 37 | + |
| 38 | +You can see the changes are not deployed by running `amplify status` and then simultaneously build & deploy your site with `amplify publish`. Once complete your application will be visible from an S3 hosting bucket for testing, and it is also fronted with a CloudFront Distribution. |
| 39 | + |
| 40 | +# Add User Registration and Sign-In |
| 41 | + |
| 42 | +Now that your app is in the cloud, you can add some features like allowing users to register for your site and login. Run `amplify add auth` and select the **Default** |
| 43 | + |
| 44 | +Next, add the Amplify library to your application: |
| 45 | +``` |
| 46 | +yarn add aws-amplify aws-amplify-react |
| 47 | +``` |
| 48 | + |
| 49 | +You should see a `/src/aws-exports.js` file created which will have all of the appropriate cloud resources defined for your application. Edit `./src/App.js` to include the Amplify library, configs, and [React HOC](https://reactjs.org/docs/higher-order-components.html). Then initialize the library: |
| 50 | + |
| 51 | +``` |
| 52 | +import Amplify from 'aws-amplify'; |
| 53 | +import aws_exports from './aws-exports'; |
| 54 | +import { withAuthenticator } from 'aws-amplify-react'; |
| 55 | +Amplify.configure(aws_exports); |
| 56 | +``` |
| 57 | + |
| 58 | +Then wrap the default `App` component using `withAuthenticator` at the bottom of the file: |
| 59 | + |
| 60 | +``` |
| 61 | +export default withAuthenticator(App, true); |
| 62 | +``` |
| 63 | + |
| 64 | +You can now use `amplify publish` to build and publish your app again. This time you'll be able to register a new user and sign-in before entering the main application. |
| 65 | + |
| 66 | +# Add Analytics and Storage |
| 67 | + |
| 68 | +A login screen is nice but now is the time to add some features, like tracking analytics of user behavior and uploading/downloading images in the cloud. Start by running `amplify add analyitcs` in your project. Then run `amplify add storage` and select the S3 provider. When complete run `amplify push` and the cloud resources will be created. |
| 69 | + |
| 70 | +Edit your `App.js` file in the React project again and modify your imports so that the `Analytics` and `Storage` categories are included as well as the `S3Album` component, which will be used for uploading and downloading photos. |
| 71 | + |
| 72 | +``` |
| 73 | +import { Analytics, Storage } from 'aws-amplify'; |
| 74 | +import { withAuthenticator, S3Album } from 'aws-amplify-react'; |
| 75 | +``` |
| 76 | + |
| 77 | +The `Analytics` category will automatically track user session data such as sign-in events, however you can record custom events or metrics at any time. You can also use the `Storage` category to upload files to a private user location after someone has logged in. First, add the following line after `Amplify.configure()` has been called: |
| 78 | + |
| 79 | +`Storage.configure({ level: 'private' });` |
| 80 | + |
| 81 | +Next, add the following methods before the component's `render` method: |
| 82 | + |
| 83 | +``` |
| 84 | + uploadFile = (evt) => { |
| 85 | + const file = evt.target.files[0]; |
| 86 | + const name = file.name; |
| 87 | +
|
| 88 | + Storage.put(name, file).then(() => { |
| 89 | + this.setState({ file: name }); |
| 90 | + }) |
| 91 | + } |
| 92 | +
|
| 93 | + componentDidMount() { |
| 94 | + Analytics.record('Amplify_CLI'); |
| 95 | + } |
| 96 | +``` |
| 97 | + |
| 98 | +Finally, modify the `render` method so that you can upload files and also view any of the "private" photos that have been added for the logged in user: |
| 99 | + |
| 100 | +``` |
| 101 | + render() { |
| 102 | + return ( |
| 103 | + <div className="App"> |
| 104 | + <p> Pick a file</p> |
| 105 | + <input type="file" onChange={this.uploadFile} /> |
| 106 | + <S3Album level="private" path='' /> |
| 107 | + </div> |
| 108 | + ); |
| 109 | + } |
| 110 | +``` |
| 111 | +Refresh the web page manually to see the uploaded image in your app. |
| 112 | + |
| 113 | +Save your changes and run `amplify publish`. Since you already pushed the changes earlier just the local build will be created and uploaded to the hosting bucket. Login as before if necessary and you'll be able to upload photos, which are protected by user. You can also refresh the page to view them. |
| 114 | + |
| 115 | + |
| 116 | +# Add REST API calls to a database |
| 117 | + |
| 118 | +Now that your application is setup, the final piece is to add a backend API with data that can be peristed in a database. For this example we will use a REST backend with a NoSQL database. Run `amplify add api` and follow the prompts, giving your API a friendly name such as **myapi** or something else that you remember. Use the default `/items` path and select **Create a new lambda function**. Select the option titled **CRUD function for Amazon DynamoDB table (Integration with Amazon API Gateway and Amazon DynamoDB)** when prompted. This will create an architecture of Amazon API Gateway with Express running in a Lambda function that reads and writes to Amazon DynamoDB. You'll be able to later modify the routes in the Lambda function to meet your needs and update it in the cloud. |
| 119 | + |
| 120 | +Since you do not have a database provisioned yet, the CLI workflow will prompt you for this. Alternatively, you could have run `amplify add storage` beforehand to create a DynamoDB table and use it in this setup. When the CLI asks you for the Primary Key structure use an attribute named `id` of type `String`. |
| 121 | +Next, you would need to select the security type for the API. Select **Authenticated - AWS IAM (Signature Version 4 signing** option. |
| 122 | + |
| 123 | + |
| 124 | +Edit your `App.js` file in the React project again and modify your imports so that the `API` category is included as well to make API calls from the app. |
| 125 | + |
| 126 | +``` |
| 127 | +import { Analytics, Storage, API } from 'aws-amplify'; |
| 128 | +``` |
| 129 | + |
| 130 | + |
| 131 | +In `App.js` add in the following code before the `render()` method, update **myapi** if you used an alternative name during setup: |
| 132 | +``` |
| 133 | + post = async () => { |
| 134 | + console.log('calling api'); |
| 135 | + const response = await API.post('myapi', '/items', { |
| 136 | + body: { |
| 137 | + id: '1', |
| 138 | + name: 'hello amplify!' |
| 139 | + } |
| 140 | + }); |
| 141 | + alert(JSON.stringify(response, null, 2)); |
| 142 | + } |
| 143 | + get = async () => { |
| 144 | + console.log('calling api'); |
| 145 | + const response = await API.get('myapi', '/items/object/1'); |
| 146 | + alert(JSON.stringify(response, null, 2)); |
| 147 | + } |
| 148 | + list = async () => { |
| 149 | + console.log('calling api'); |
| 150 | + const response = await API.get('myapi', '/items/1'); |
| 151 | + alert(JSON.stringify(response, null, 2)); |
| 152 | + } |
| 153 | + ``` |
| 154 | + |
| 155 | +Update the `render()` method to include calls to these three methods: |
| 156 | +``` |
| 157 | + render() { |
| 158 | + return ( |
| 159 | + <div className="App"> |
| 160 | + <p> Pick a file</p> |
| 161 | + <input type="file" onChange={this.uploadFile} /> |
| 162 | + <button onClick={this.post}>POST</button> |
| 163 | + <button onClick={this.get}>GET</button> |
| 164 | + <button onClick={this.list}>LIST</button> |
| 165 | + |
| 166 | + <S3Album level="private" path='' /> |
| 167 | + </div> |
| 168 | + ); |
| 169 | + } |
| 170 | + ``` |
| 171 | + |
| 172 | +Save the file and run `amplify publish`. After the API is deployed along with the Lambda function and database table, your app will be built and updated in the cloud. You can then add a record to the database by clicking **POST** and use **GET** or **LIST** to retrieve the record, which has been hard coded in this simple example. |
| 173 | + |
| 174 | +In your project directory, open `./amplify/backend/function` and you will see the Lambda function that you created. The `app.js` file runs the Express function and all of the HTTP method routes are available for you to manipulate. For instance the `API.post()` in your React app corresponded to the `app.post(path, function(req, res){...})` code in this Lambda function. If you choose to customize the Lambda you can always update it in the cloud with `amplify push`. |
0 commit comments