---
# System prepended metadata

title: AWS Amplify

---

#### AWS Learning Group - 2022/10/13
# AWS Amplify

:::spoiler **Table of Content**
1. About AWS Amplify
2. IAM
3. Install and configure the Amplify CLI
4. Set up fullstack project
5. Initialize a new backend
6. Connect API and database to the app
7. Deploy and host app
:::





## About AWS Amplify
前言
> AWS Amplify 是一套端對端解決方案，可讓行動和前端 Web 開發人員建置和採用 AWS 技術的安全、可擴充完整堆疊應用程式。透過 Amplify，您可以在數分鐘內完成設定應用程式後端，以數行程式碼將其連接至您的應用程式，並在三個步驟內完成部署靜態 Web 應用程式。透過 AWS Amplify 更快速進入市場。

參考: https://docs.amplify.aws/start/q/integration/js/
## Install and configure the Amplify CLI
1.首先要安裝amplify的CLI套件
```
npm install -g @aws-amplify/cli
```
2.初始設定
```
amplify configure
```

```
Specify the AWS Region
? region:  us-east-1   //可以替換
Specify the username of the new IAM user:
? user name:  amplify_test   //可以替換
Complete the user creation using the AWS console: <URL>
```
3.接下來應該會自動跳到創建 `IAM` User的頁面, 都使用預設設定就可以了！
Policy 的部份預設會套用 `AdministratorAccess-Amplify` 讓使用者可以存取大部分 Amplify相關的功能
![](https://docs.amplify.aws/images/user-creation.gif)

4.最後可以停在有顯示`Access key ID` 跟 `Secret access key` 的頁面並回到Terminal 輸入資料
```
Enter the access key of the newly created user:
? accessKeyId:  <貼上剛剛的 accessKeyId>
? secretAccessKey:  <貼上剛剛的 secretAccessKey>
This would update/create the AWS Profile in your local machine
? Profile Name: default
```
5.到這步使用者就已經創建完成了！


## Set up fullstack project
接下來要建立一個簡單的範例網站

1.打開Terminal並移動到你想存放網站資料的目錄下
```bash
mkdir -p amplify-js-app/src && cd amplify-js-app
touch package.json index.html webpack.config.js src/app.js
```

App 的檔案結構大致會如下
```
amplify-js-app
├── index.html
├── package.json
├── src
│   └── app.js
└── webpack.config.js
```
2.修改 `package.json`
```javascript=
{
  "name": "amplify-js-app",
  "version": "1.0.0",
  "description": "Amplify JavaScript Example",
  "dependencies": {
    "aws-amplify": "latest"
  },
  "devDependencies": {
    "copy-webpack-plugin": "^6.1.0",
    "webpack": "^4.46.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^4.4.0"
  },
  "scripts": {
    "start": "webpack && webpack-dev-server --mode development",
    "build": "webpack"
  }
}
```
3.安裝剛剛設定的套件
```
npm install
```
4.修改 `index.html`
```html=
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Amplify</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      html,
      body {
        font-family: 'Amazon Ember', 'Helvetica', 'sans-serif';
        margin: 0;
      }
      a {
        color: #ff9900;
      }
      h1 {
        font-weight: 300;
      }
      hr {
        height: 1px;
        background: lightgray;
        border: none;
      }
      .app {
        width: 100%;
      }
      .app-header {
        color: white;
        text-align: center;
        background: linear-gradient(30deg, #f90 55%, #ffc300);
        width: 100%;
        margin: 0 0 1em 0;
        padding: 3em 0 3em 0;
        box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.3);
      }
      .app-logo {
        width: 126px;
        margin: 0 auto;
      }
      .app-body {
        width: 400px;
        margin: 0 auto;
        text-align: center;
      }
      .app-body button {
        background-color: #ff9900;
        font-size: 14px;
        color: white;
        text-transform: uppercase;
        padding: 1em;
        border: none;
      }
      .app-body button:hover {
        opacity: 0.8;
      }
    </style>
  </head>

  <body>
    <div class="app">
      <div class="app-header">
        <div class="app-logo">
          <img
            src="https://aws-amplify.github.io/images/Logos/Amplify-Logo-White.svg"
            alt="AWS Amplify"
          />
        </div>
        <h1>Welcome to Amplify</h1>
      </div>
      <div class="app-body">
        <h1>Mutation Results</h1>
        <button id="MutationEventButton">Add data</button>
        <div id="MutationResult"></div>
        <hr />

        <h1>Query Results</h1>
        <div id="QueryResult"></div>
        <hr />

        <h1>Subscription Results</h1>
        <div id="SubscriptionResult"></div>
      </div>
    </div>
    <script src="main.bundle.js"></script>
  </body>
</html>
```

5.修改 `webpack.config.js`

```javascript=
const CopyWebpackPlugin = require('copy-webpack-plugin');
const webpack = require('webpack');
const path = require('path');

module.exports = {
  mode: 'development',
  entry: './src/app.js',
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/
      }
    ]
  },
  devServer: {
    client: {
      overlay: true
    },
    hot: true,
    watchFiles: ['src/*', 'index.html']
  },
  plugins: [
    new CopyWebpackPlugin({
      patterns: ['index.html']
    }),
    new webpack.HotModuleReplacementPlugin()
  ]
};
```
6.執行應用程式
```
npm start
```
7.開啟瀏覽器 然後前往 http://localhost:8080 , 到這步我們已經完成Front-end的架設，接下來要建立Backend的部份!

## Initialize a new backend

1.在剛剛建立的 `amplify-js-app`目錄下開啟 Terminal並執行
```
amplify init
```
會有一些東西需要設定，選項的部份都使用預設的就可以了
```
? Enter a name for the project: amplifyjsapp
The following configuration will be applied:

Project information
| Name: amplifyjsapp
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: none
| Source Directory Path: src
| Distribution Directory Path: dist
| Build Command: npm run-script build
| Start Command: npm run-script start

? Initialize the project with the above configuration? Yes
Using default provider  awscloudformation
? Select the authentication method you want to use: AWS profile

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html

? Please choose the profile you want to use: default
```

2.執行完之後就建立好Backend的部份 接下來要套用API才能讓我們對雲端伺服器進行資料的讀寫.

## Connect API and database to the app
### Create GraphQL API and database

1.新增 `GraphQL` API到我們剛剛建立好的Project
```
amplify add api
```
使用預設設定
```
? Select from one of the below mentioned services:
# GraphQL
? Here is the GraphQL API that we will create. Select a setting to edit or continue
# Continue
? Choose a schema template:
# Single object with fields (e.g., “Todo” with ID, name, description)
✔ Do you want to edit the schema now? (Y/n)
# Yes
```
之後 CLI 應該會在你的文字編輯器開啟一個GraphQL的schema檔案 
(通常 schema 指 資料表及欄位的設計)
```
# This "input" configures a global authorization rule to enable public access to
# all models in this schema. Learn more about authorization rules here: https://docs.amplify.aws/cli/graphql/authorization-rules
input AMPLIFY { globalAuthRule: AuthRule = { allow: public } } # FOR TESTING ONLY!

type Todo @model {
  id: ID!
  name: String!
  description: String
}
```
這邊直接按Enter即可

### Deploy your GraphQL API
前面的步驟已經在本地建置好API了,接下來要將剛剛新增的`GraphQL` API部署到雲端上
```
amplify push
```
在push之後 系統會詢問我們是否要產生 GraphQL 的程式碼範例,包含了針對 GraphQL的相關操作(create, read, delete, list, update)讓我們可以更簡單的去使用這些功能, 照著下面選項設定即可

```
? Do you want to generate code for your newly created GraphQL API (Yes)
? Choose the code generation language target (javascript)
? Enter the file name pattern of graphql queries, mutations and subscriptions (src/graphql/**/*.js)
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions (Yes)
? Enter maximum statement depth [increase from default if your schema is deeply nested] (2)
```

### API Testing 
可以透過這條指令開啟一個AWS的console來對你的API進行操作例如：從database query資料 或是新增資料到database...等
```
amplify console api
```

example:
![](https://i.imgur.com/THGlYd4.png)

### Connect frontend to api

接下來要將我們的api和前端串連起來, 修改Project資料夾的 `src/app.js`

```javascript=
import { Amplify, API, graphqlOperation } from "aws-amplify";

import awsconfig from "./aws-exports";
import { createTodo } from "./graphql/mutations";
import { listTodos } from "./graphql/queries";
import { onCreateTodo } from "./graphql/subscriptions";

Amplify.configure(awsconfig);

async function createNewTodo() {
  const todo = {
    name: "Use AppSync",
    description: `Realtime and Offline (${new Date().toLocaleString()})`,
  };

  return await API.graphql(graphqlOperation(createTodo, { input: todo }));
}

async function getData() {
  API.graphql(graphqlOperation(listTodos)).then((evt) => {
    evt.data.listTodos.items.map((todo, i) => {
      QueryResult.innerHTML += `<p>${todo.name} - ${todo.description}</p>`;
    });
  });
}


const MutationButton = document.getElementById("MutationEventButton");
const MutationResult = document.getElementById("MutationResult");
const QueryResult = document.getElementById("QueryResult");
const SubscriptionResult = document.getElementById("SubscriptionResult");

MutationButton.addEventListener("click", (evt) => {
  createNewTodo().then((evt) => {
    MutationResult.innerHTML += `<p>${evt.data.createTodo.name} - ${evt.data.createTodo.description}</p>`;
  });
});

API.graphql(graphqlOperation(onCreateTodo)).subscribe({
  next: (evt) => {
    const todo = evt.value.data.onCreateTodo;
    SubscriptionResult.innerHTML += `<p>${todo.name} - ${todo.description}</p>`;
  },
});



getData();
```

修改好了之後儲存 並重新執行一次
```
npm start
```
:::info
此時我們的網站有的功能
1.點擊`ADD DATA`會新增一筆資料到我們的Database裡並且在 `Subscription Result` 的地方顯示我們剛剛新增的資料
2.Query Results 會把現在Database有的資料都顯示出來 格式是 (name , description)
:::

## Deploy and host app
接下來在Project的 root 目錄下打開 Terminal 並輸入
```
amplify add hosting
```
```
? Select the plugin module to execute: Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
? Choose a type: Manual Deployment
```
再輸入
```
amplify publish
```
等跑完之後最下面會出現部署好的網址
![](https://i.imgur.com/MfHkreR.png)

整個部屬就完成了！ :fireworks: 

---

我們可以開啟剛剛的 `amplify console api` 來試著直接操作API的功能

包括
#### Query
- getTodo()
- listTodo()
#### Mutation
- createTodo()
- deleteTodo()
- updateTodo()
