AWS Amplify フレームワーク 入門メモ

# 概要

AWS Amplify(アンプリファイ) フレームワークの入門ページ ([Getting Started] (https://aws-amplify.github.io/docs/js/start?platform=purejs)) を読みながら、基本的な利用方法を学んだときのメモです。

**環境**

* Windows 10 Professional 1903
* aws CLI 2.0.7
* amplify CLI 4.18.0
* Node.js 12.16.2
* npm 6.14.4

**参考**

* [AWS Amplify] (https://aws.amazon.com/jp/amplify/)
* [Amplify フレームワーク] (https://aws.amazon.com/jp/amplify/framework/)

# Amplify CLIのインストールと設定

Amplify CLIは、Amplifyフレームワークのコンポーネントの1つで、コマンドラインでプロジェクトの作成やバックエンドサービスの構築が行えます。

## 前提

Amplify CLIのインストールにはNode.js 8.x以上、npm 5.x以上が必要です。

```console
> node -v
v12.16.2

> npm -v
6.14.4
```

また、AWS CLIは必要ありませんがバージョンを補足しておきます。

```console
> aws --version
aws-cli/2.0.7 Python/3.7.5 Windows/10 botocore/2.0.0dev11
```

## インストール

npmでインストールします。

```console
> npm install -g @aws-amplify/cli

// 省略

----------------------------------------
Successfully installed the Amplify CLI
----------------------------------------


JavaScript Getting Started - https://aws-amplify.github.io/docs/js/start


Android Getting Started - https://aws-amplify.github.io/docs/android/start


iOS Getting Started - https://aws-amplify.github.io/docs/ios/start

// 省略

+ @aws-amplify/cli@4.18.0
added 1048 packages from 713 contributors in 225.911s
```

バージョン確認

```console
> amplify --version
Scanning for plugins...
Plugin scan successful
4.18.0
```

`@aws-amplify/cli`をインストールした後に、インストールしたパッケージの一覧を表示すると、下記のメッセージが複数行表示されます。

```console
> npm -g ls -depth=0

npm ERR! peer dep missing: inquirer@^5.0.0 || ^6.0.0, required by inquirer-autocomplete-prompt@1.0.2
// 複数行表示される
```

バグ([Peer dependency missing #3284] (https://github.com/aws-amplify/amplify-cli/issues/3284))のようですが動作には影響はないようです。

## 設定

> Configures the attributes of your project for amplify-cli, such as switching front-end framework and adding/removing cloud-provider plugins.
> \-------------------------------------------------------------------------------------
> フロントエンドフレームワークの切り替えやクラウドプロバイダープラグインの追加/削除など、amplify-cliのプロジェクトの属性を構成します。

設定は`amplify configure`コマンドで行います。設定は対話形式で行われ、途中AWSコンソールで新しいIAMユーザーの登録を行う場面があります。

```console
> amplify configure

Follow these steps to set up access to your AWS account:
Sign in to your AWS administrator account:
https://console.aws.amazon.com/
Press Enter to continue
```

この時点でブラウザにAWSコンソールのログインページが表示されるので管理者アカウントでログインします。
ログインできたら<kbd>Enter</kbd>を押して進めます。

続いてリージョンを選択し(この例では`ap-northeast-1`)、追加するIAMユーザー名を入力します。デフォルトで`amplify-{ランダムな英数字}`が表示されているので、このままでよければ<kbd>Enter</kbd>を押し、別の名前がよければ入力します。

```console
Specify the AWS Region
? region:  ap-northeast-1
Specify the username of the new IAM user:
? user name:  amplify-8ZcOy
Complete the user creation using the AWS console
https://console.aws.amazon.com/iam/home?region=undefined#/users$new?step=final&accessKey&userNames=amplify-8ZcOy&permissionType=policies&policies=arn:aws:iam::aws:policy%2FAdministratorAccess
Press Enter to continue
```

ウィザード形式のIAMユーザーの追加ページが表示されるので、指示に従って設定します。基本はデフォルトのままで構わないと思います。
IAMユーザーの追加が出来たら<kbd>Enter</kbd>を押して進めます。
![amplify-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/148838ff-d6c7-a795-cd22-006e473bb8a4.png)
![amplify-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/cc0bcbcd-5c89-c271-8bc2-1dcb20840b36.png)
![amplify-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/df704032-8b43-29b7-08e9-dc124e7e259c.png)
![amplify-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/090f0b92-62d8-7efe-1fc0-cbd8a6133cd2.png)
![amplify-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/bc4eb3a7-b082-aa1b-d3b1-506e22b08732.png)

追加したIAMユーザーのアクセスキーIDとシークレットアクセスキーを入力し、新しいプロファイルを作成します。
プロファイル名はユーザー名と同じにしています。

```console
Enter the access key of the newly created user:
? accessKeyId:  XXXXXXXXXXXX**********
? secretAccessKey:  XXXXXXXXXXXXXXXXXXXX********************
This would update/create the AWS Profile in your local machine
? Profile Name:  amplify-8ZcOy

Successfully set up the new user.
```

以上で設定は完了です。

念のためAWS CLIで登録したプロファイルを確認してみます。

```console
> aws configure list --profile amplify-8ZcOy

      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile            amplify-8ZcOy           manual    --profile
access_key     ****************XXXX shared-credentials-file
secret_key     ****************XXXX shared-credentials-file
    region           ap-northeast-1      config-file    ~/.aws/config
```


# Webアプリケーションのプロジェクトを作成

AmplifyフレームワークではiOS、Android、Web、React Nativeなどのアプリケーションと統合するためのライブラリやUIコンポーネントを提供しています。

UIコンポーネントについては[A beautiful component library connected to the cloud] (https://aws-amplify.github.io/media/ui_library)で確認できます。
![get_started.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/786f12d4-1e2f-f4c9-2f2e-6104e9637805.png)
この記事ではJavaScriptを利用したWebアプリケーションの[Getting Started] (https://aws-amplify.github.io/docs/)ページを参考に、静的Webサイトの作成とS3へホスティングするまでの手順を確認します。

JavaScriptのフレームワークでは[Angular] (https://angular.io/)、[Ember.js] (https://emberjs.com/)、[Ionic] (https://ionicframework.com/)、[React] (https://reactjs.org/)、[Vue] (https://vuejs.org/index.html)がサポートされています。

## プロジェクトのひな型を準備

`demo-amplify-js-app`というフォルダを作成し、下記の空ファイルを作成します。

```text
demo-amplify-js-app
  |
  `--- /src
  |     |
  |     `--- app.js
  |
  `--- index.html
  `--- package.json
  `--- webpack.config.js
```

このうち`index.html`、`package.json`、`webpack.config.js`は、[Step 1. Create a New App] (https://aws-amplify.github.io/docs/js/start?platform=purejs) に記載されているコードをコピー＆ペーストし、`npm install`で依存パッケージをインストールします。
図はこの時点でのプロジェクトフォルダをVSCodeで開いた状態です。
![project-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/e6f61925-008b-c3d8-2f01-875a0de111e1.png)
インストールが終わったら、ローカルで動作確認するために`npm start`でアプリケーションを起動し、下記のURLにアクセスします。

```text
http://localhost:8080
```

正常に起動していれば図のページが表示されます。（ADD DATAというボタンがありますが、この段階では機能しません）
![amplify-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/e950c4d1-c000-5e16-8af0-bbccd39f72c2.png)

以上でプロジェクトのひな型の準備は完了です。

## プロジェクトの初期化

### amplify init

> Initializes a new project, sets up deployment resources in the cloud, and makes your project ready for Amplify.
> \------------------------------------------------------------------------------------
> 新しいプロジェクトを初期化し、クラウドにデプロイリソースを設定して、プロジェクトをAmplifyに対応させます。

初期化は`amplify init`コマンドで行います。プロジェクトの初期化は対話形式で行われます。
行頭に`?`がある行が入力/選択する項目です。
環境(`environment`)の名前を入力する項目がありますが、ここではproductionの意味で`prod`と入力しています。環境とはいわゆる"本番環境"や"開発環境"のことで、amplifyコマンドは環境名を指定して複数の環境を切り替えることができます。

```console
> amplify init

Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project demo-amplify-js-app
? Enter a name for the environment prod
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using none
? Source Directory Path:  src
? Distribution Directory Path: dist
? Build Command:  npm.cmd run-script build
? Start Command: npm.cmd run-script start
Using default provider  awscloudformation

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

続いてプロファイルを使用するか聞かれるので`Yes`を選択し、`amplify configure`で作成したプロファイルを選びます。（この例では`amplify-8ZcOy`）
この後プロジェクトの初期化処理が行われ、AWS上にいくつかリソースが追加されます。

```console
? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use amplify-8ZcOy
Adding backend environment dev to AWS Amplify Console app: xxxxxxxxxxxxxx
- Initializing project in the cloud...

// 省略

Your project has been successfully initialized and connected to the cloud!

Some next steps:
"amplify status" will show you what you've added already and if it's locally configured or deployed
"amplify add <category>" will allow you to add features like user login or a backend API
"amplify push" will build all your local backend resources and provision it in the cloud
“amplify console” to open the Amplify Console and view your project status
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

Pro tip:
Try "amplify add api" to create a backend API and then "amplify publish" to deploy everything
```

#### initで作成されるAWSのリソース

AWS上に以下のリソースが作成されます。ちなみにリソースというのはS3やDynamoDBのことです。

##### Amplify Console

`demo-amplify-js-app`というアプリケーションが作成されています。
![init-amplify-dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/b1aefac5-9483-1d72-60f0-9e36ca18a059.png)
![init-amplify-console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/bcca49e7-78c7-1eb9-2629-6b39e64e9fd7.png)

##### CloudFormation

Stackが作成されています。
`amplify-demo-amplify-js-app-prod-213624`
![init-cloudformation-stack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/ab8ca0dc-a246-5def-f1a2-bfc4c022a1f6.png)

##### S3

デプロイ用のバケットが作成されています。
`amplify-demo-amplify-js-app-prod-213624-deployment`
![init-s3-bucket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/4e335e78-0671-a267-eed7-cf653c4e6db5.png)

##### Roles

ロールが作成されています。
`amplify-demo-amplify-js-app-prod-213624-authRole`
`amplify-demo-amplify-js-app-prod-213624-unauthRole`
![init-roles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/85cdec22-6a52-78be-6885-dd712fe89573.png)

#### init後のプロジェクト

初期化が終わるとプロジェクトに`amplify`ディレクトリをはじめいくつかのファイルが追加されます。
![project-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/f60aa331-d191-bc12-7b77-bb3dff371272.png)

```text
demo-amplify-js-app
  |
  `--- /amplify               <--- add
  |      |
  |      `--- /.config
  |      |      |
  |      |      `--- local-aws-info.json
  |      |      `--- local-env-info.json
  |      |      `--- project-config.json
  |      |
  |      `--- /#current-cloud-backend
  |      |      |
  |      |      `--- amplify-meta.json
  |      |
  |      `--- /backend
  |      |      |
  |      |      `--- amplify-meta.json
  |      |      `--- backend-config.json
  |      |
  |      `--- teram-provider-info.json
  |
  `--- /dist
  `--- /node_modules
  `--- /src
  |     |
  |     `--- app.js
  |     `--- aws-exports.js   <--- add
  |
  `--- .gitignore             <--- add
  `--- index.html
  `--- package.json
  `--- package-lock.json
  `--- webpack.config.js
```

### プロジェクトのgit管理

initで`.gitignore`ファイルが下記の内容で作成されています。このようにバージョン管理する必要のないファイル又はしてはいけないファイルが決まっています。
今後のプロジェクトの更新内容を把握しやすいようにこの時点でgitリポジトリ化します。

```text
#amplify
amplify/\#current-cloud-backend
amplify/.config/local-*
amplify/mock-data
amplify/backend/amplify-meta.json
amplify/backend/awscloudformation
build/
dist/
node_modules/
aws-exports.js
awsconfiguration.json
amplifyconfiguration.json
amplify-build-config.json
amplify-gradle-config.json
amplifyxc.config
```

### amplify status

> Shows the state of local resources not yet pushed to the cloud (Create/Update/Delete).
> \-------------------------------------------------------------------------------------
> まだクラウドにプッシュされていないローカルリソースの状態を表示します（Create/Update/Delete）。

`amplify status`コマンドでプロジェクトが利用するリソースを確認できます。`init`直後はAWS上に反映するリソースはないので、下記のように空のテーブルが表示されます。

```console
> amplify status

Current Environment: prod

| Category | Resource name | Operation | Provider plugin |
| -------- | ------------- | --------- | --------------- |
```

## プロジェクトにAPIを追加する

### amplify add api

> Adds a resource for an Amplify category in your local backend
> \-------------------------------------------------------------
> ローカルバックエンドのAmplifyカテゴリのリソースを追加します 

`amplify add api`コマンドでAPIを追加します。このコマンドも対話形式で設定を行います。
APIの選択肢には`REST`と`GraphQL`があります。ここでは`GraphQL`を選択し、API名を`todo`としました。
またスキーマを作成するかどうか聞かれるので`Yes`を選択し、"Todo"というスキーマを選びました。（※このスキーマは説明用のサンプルで作成しないことも可能です。また"Posts"という少し複雑なスキーマを選ぶこともできます。）

```console
> amplify add api

? Please select from one of the below mentioned services: GraphQL
? Provide API name: todo
? Choose the default authorization type for the API API key
? Enter a description for the API key: todo api
? After how many days from now the API key should expire (1-365): 7
? Do you want to configure advanced settings for the GraphQL API No, I am done.
? Do you have an annotated GraphQL schema? No
? Do you want a guided schema creation? Yes
? What best describes your project: Single object with fields (e.g., “Todo” with ID, name, description)
? Do you want to edit the schema now? No

The following types do not have '@auth' enabled. Consider using @auth with @model
         - Todo
Learn more about @auth here: https://aws-amplify.github.io/docs/cli-toolchain/graphql#auth


GraphQL schema compiled successfully.

Edit your schema at D:\dev\vsc-workspace\demo-amplify-js-app\amplify\backend\api\todo\schema.graphql or place .graphql files in a directory at D:\dev\vsc-worksp
ace\demo-amplify-js-app\amplify\backend\api\todo\schema
Successfully added resource todo locally

Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
```

#### add api後のプロジェクト

`amplify/backend/api`下にファイルが作成されています。（更新のあるファイルはこの後コミットします）
![project-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/4d9e0111-9eeb-86e3-7f02-159bbda72391.png)

```text
demo-amplify-js-app
  |
  `--- /amplify
  |      |
  |      `--- /.config
  |      |      |
  |      |      `--- local-aws-info.json
  |      |      `--- local-env-info.json
  |      |      `--- project-config.json
  |      |
  |      `--- /#current-cloud-backend
  |      |      |
  |      |      `--- amplify-meta.json
  |      |
  |      `--- /backend
  |      |      |
  |      |      `--- /api                      <--- add
  |      |      |      |
  |      |      |      `--- /todo              <--- amplify add apiで指定したAPI名
  |      |      |             |
  |      |      |             `--- /build
  |      |      |             `--- /resolvers
  |      |      |             `--- /stacks
  |      |      |             |      |
  |      |      |             |      `--- CustomResources.json
  |      |      |             |
  |      |      |             `--- parameters.json
  |      |      |             `--- schema.graphql
  |      |      |             `--- transform.config.json
  |      |      |
  |      |      `--- amplify-meta.json
  |      |      `--- backend-config.json      <--- modify
  |      |
  |      `--- teram-provider-info.json
  |
  `--- /dist
  `--- /node_modules
  `--- /src
  |     |
  |     `--- app.js
  |     `--- aws-exports.js
  |
  `--- .gitignore
  `--- index.html
  `--- package.json
  `--- package-lock.json
  `--- webpack.config.js
```

コマンド実行時の対話で"Todo"というスキーマを作成すると答えたので、`amplify/backend/api/todo`に下記のschema.graphqlというファイルが作成されています。

```graphql:schema.graphql
type Todo @model {
  id: ID!
  name: String!
  description: String
}
```

#### add api後のステータス

下記がAPI追加後のステータスになります。Operationが`Create`となっていますが、これはAWS上に反映するとこのAPIのリソースが作成されるという意味になります。
なお、GraphQLでは`AppSync`と`DynamoDB`がリソースとして作成されます。

```console
> amplify status

Current Environment: prod

| Category | Resource name | Operation | Provider plugin   |
| -------- | ------------- | --------- | ----------------- |
| Api      | todo          | Create    | awscloudformation |
```

### amplify push

> Provisions cloud resources with the latest local developments.
> \------------------------------------------------------------
> 最新のlocal developmentsでクラウドリソースをプロビジョニングします。

ローカルの状態をAWSへ反映するには`amplify push`コマンドで行います。途中でGraphQL APIを操作するコードを生成するか、言語は何にするか(JavaScript, TypeScript, flow)を聞かれます。
ここではJavaScriptでコードを生成するように答えています。

```console
> amplify push

√ Successfully pulled backend environment dev from the cloud.

Current Environment: prod

| Category | Resource name | Operation | Provider plugin   |
| -------- | ------------- | --------- | ----------------- |
| Api      | todo          | Create    | awscloudformation |
? Are you sure you want to continue? Yes

The following types do not have '@auth' enabled. Consider using @auth with @model
         - Todo
Learn more about @auth here: https://aws-amplify.github.io/docs/cli-toolchain/graphql#auth


GraphQL schema compiled successfully.

Edit your schema at D:\dev\vsc-workspace\demo-amplify-js-app\amplify\backend\api\todo\schema.graphql or place .graphql files in a directory at D:\dev\vsc-worksp
ace\demo-amplify-js-app\amplify\backend\api\todo\schema
? 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
/ Updating resources in the cloud. This may take a few minutes...

// 省略

√ Generated GraphQL operations successfully and saved at src\graphql
√ All resources are updated in the cloud

GraphQL endpoint: https://xxxxxxxxxxxxxxxxxxxxxxxxxx.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: xxx-xxxxxxxxxxxxxxxxxxxxxxxxxx
```

#### pushで作成されるAWSのリソース

##### Amplify Console

`GraphQL API`が登録されています。
![push-amplify-console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/9df06d9c-3a51-33b9-60ab-5a1b3ed8ad1f.png)

##### AppSync

スキーマやデータソースが作成されています。
![push-appsync-schema.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/9d3992f2-e175-ace7-efc2-11b6b9983518.png)
![push-appsync-datasource.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/8623b844-ada5-20c8-b7b4-2b059510eb7a.png)
設定ではAPIのエンドポイントおよび認証モードが確認できます。
![push-appsync-setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/3405ee83-1d75-1aa5-7954-a83eb3bf88b2.png)
![push-appsync-setting-api-key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/503e614f-e309-d926-88ee-3b71d5a4e533.png)

##### DynamoDB

GraphQLのデータソースとしてDynamoDBにテーブルが作成されています。
`Todo-2z5lybtblrgrpptu4job3mevma-prod`
![push-dynamodb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/4f2a8a1a-ad7c-faaa-d673-d575662cc1e5.png)

##### Roles

DynamoDBアクセス用のロールが作成されています。
`Todo-role-2z5lybtblrgrpptu4job3mevma-prod`
![push-roles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/19b0110a-e095-5166-f1c7-b4f33455c2fd.png)

##### CloudFormation

Stackが作成されています。
`amplify-demo-amplify-js-app-prod-213624-apitodo-UKR1WF6DW3EC`
`amplify-demo-amplify-js-app-prod-213624-apitodo-UKR1WF6DW3EC-Todo-EYNHDFHQODJM`
`amplify-demo-amplify-js-app-prod-213624-apitodo-UKR1WF6DW3EC-CustomResourcesjson-HQXMZNPER244`
![push-cloudformation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/4d2ae567-6718-9c9a-d911-2b6393f74b3f.png)

#### push後のプロジェクト

`src/graphql`下にGraphQL APIを操作するコードが生成されています。

![project-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/6fb0041f-2c3b-93ac-b9c8-3c1317dafcab.png)

```text
demo-amplify-js-app
  |
  `--- /amplify
  |      |
  |      `--- /.config
  |      |      |
  |      |      `--- ...省略...
  |      |
  |      `--- /#current-cloud-backend
  |      |      |
  |      |      `--- /api                     <--- add
  |      |      |      |
  |      |      |      `--- /todo
  |      |      |             |
  |      |      |             `--- /build
  |      |      |             `--- /resolvers
  |      |      |             `--- /stacks
  |      |      |             |      |
  |      |      |             |      `--- CustomResources.json
  |      |      |             |
  |      |      |             `--- parameters.json
  |      |      |             `--- schema.graphql
  |      |      |             `--- transform.config.json
  |      |      |
  |      |      `--- amplify-meta.json
  |      |      `--- backend-config.json
  |      |
  |      `--- /backend
  |      |      |
  |      |      `--- /api
  |      |      |      |
  |      |      |      `--- /todo
  |      |      |             |
  |      |      |             `--- ...省略...
  |      |      |
  |      |      `--- /awscloudformation        <-- add
  |      |      |      |
  |      |      |       `--- nested-cloudformation-stack.yml
  |      |      |
  |      |      `--- amplify-meta.json
  |      |      `--- backend-config.json
  |      |
  |      `--- teram-provider-info.json
  |
  `--- /dist
  `--- /node_modules
  `--- /src
  |     |
  |     `--- /graphql               <--- add
  |     |      |
  |     |      `--- mutations.js
  |     |      `--- queries.js
  |     |      `--- schema.json
  |     |      `--- subscrptions.js
  |     `--- app.js
  |     `--- aws-exports.js
  |
  `--- .gitignore
  `--- .graphqlconfig.yml           <--- add
  `--- index.html
  `--- package.json
  `--- package-lock.json
  `--- webpack.config.js
```

#### push後のステータス

下記がpush後のステータスです。pushが正常におこなわれたのでOperationが`No Change`となっています。

```console
> amplify status

Current Environment: prod

| Category | Resource name | Operation | Provider plugin   |
| -------- | ------------- | --------- | ----------------- |
| Api      | todo          | No Change | awscloudformation |

GraphQL endpoint: https://xxxxxxxxxxxxxxxxxxxxxxxxxx.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: xxx-xxxxxxxxxxxxxxxxxxxxxxxxxx
```

## APIの動作確認

この時点でまだ`src/app.js`は空ファイルの状態だと思います。[Step 4: Integrate into your app] (https://aws-amplify.github.io/docs/js/start?platform=purejs#step-4-integrate-into-your-app)に記載されているコードをコピー＆ペーストします。
app.jsを更新したら`npm start`コマンドでアプリケーションを起動し、下記のURLにアクセスします。

```text
http://localhost:8080
```

今度は`ADD DATA`ボタンが機能するのでクリックしてみます。すると図のように"Use AppSync - Realtime and Offline"というメッセージが表示されます。
![amplify-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/b8581cf9-0489-8b20-a33a-43266d2f3bfb.png)

**DynamoDB**

アプリケーションはローカルで動いていますが、AWS上のGraphQL APIのエンドポイントをコールしているのでAWS上のDynamoDBへデータが登録されています。
AWSコンソールのDynamoDBのダッシュボードを見るとデータが追加されていることがわかります。
![add-data-dynamodb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/909d092f-4316-aae6-8e86-10731b5a03db.png)

## 静的Webサイトのホスティング

### amplify add hosting

`amplify add hosting`コマンドでアプリケーションをS3へホスティングする準備をします。途中で`CloudFrontとS3`を利用するか、又は`S3`だけを利用するかと、公開用のバケット名を聞かれます。
ここでは`S3`だけを利用し公開バケット名はデフォルトのままとしました。
まだこの時点では公開されていません。つまりAWS上にリソースは作成されていません。

```console
> amplify add hosting

? Select the plugin module to execute Amazon CloudFront and S3
? Select the environment setup: DEV (S3 only with HTTP)
? hosting bucket name demo-amplify-js-app-20200415223152-hostingbucket
? index doc for the website index.html
? error doc for the website index.html

You can now publish your app using the following command:
Command: amplify publish
```

#### add hosting後のプロジェクト

`amplify/backend/hosting`下にファイルが作成されます。
![project-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/67e67df1-287b-f3fb-a640-faacc4f85962.png)

```text
demo-amplify-js-app
  |
  `--- /amplify
  |      |
  |      `--- /.config
  |      |      |
  |      |      `--- ...省略...
  |      |
  |      `--- /#current-cloud-backend
  |      |      |
  |      |      `--- /api
  |      |      |      |
  |      |      |      `--- /todo
  |      |      |             |
  |      |      |             `--- ...省略...
  |      |      |
  |      |      `--- amplify-meta.json
  |      |      `--- backend-config.json
  |      |
  |      `--- /backend
  |      |      |
  |      |      `--- /api
  |      |      |      |
  |      |      |      `--- /todo
  |      |      |             |
  |      |      |             `--- ...省略...
  |      |      |
  |      |      `--- /awscloudformation
  |      |      |      |
  |      |      |       `--- nested-cloudformation-stack.yml
  |      |      |
  |      |      `--- /hosting                        <--- add
  |      |      |      |
  |      |      |      `--- /S3AndCloudFront
  |      |      |             |
  |      |      |             `--- parameters.json
  |      |      |             `--- template.json
  |      |      |
  |      |      `--- amplify-meta.json
  |      |      `--- backend-config.json             <--- modify
  |      |
  |      `--- teram-provider-info.json
  |
  `--- /dist
  `--- /node_modules
  `--- /src
  |     |
  |     `--- /graphql
  |     |      |
  |     |      `--- mutations.js
  |     |      `--- queries.js
  |     |      `--- schema.json
  |     |      `--- subscrptions.js
  |     `--- app.js
  |     `--- aws-exports.js
  |
  `--- .gitignore
  `--- .graphqlconfig.yml
  `--- index.html
  `--- package.json
  `--- package-lock.json
  `--- webpack.config.js
```

#### add hosting後のステータス

下記がadd hosting後のステータスです。HostingのOperationが`Create`になっているのでAWSへの反映待ちだということがわかります。

```console
> amplify status

Current Environment: prod

| Category | Resource name   | Operation | Provider plugin   |
| -------- | --------------- | --------- | ----------------- |
| Hosting  | S3AndCloudFront | Create    | awscloudformation |
| Api      | todo            | No Change | awscloudformation |

GraphQL endpoint: https://xxxxxxxxxxxxxxxxxxxxxxxxxx.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: xxx-xxxxxxxxxxxxxxxxxxxxxxxxxx
```

### amplify publish

> Executes amplify push, and then builds and publishes client-side application for hosting.
> \--------------------------------------------------------------------------------------
> amplify pushを実行してから、ホスティング用のクライアント側アプリケーションを構築して公開します。

`amplify publish`コマンドで公開します。

```console
> amplify publish

√ Successfully pulled backend environment prod from the cloud.

Current Environment: prod

| Category | Resource name   | Operation | Provider plugin   |
| -------- | --------------- | --------- | ----------------- |
| Hosting  | S3AndCloudFront | Create    | awscloudformation |
| Api      | todo            | No Change | awscloudformation |
? Are you sure you want to continue? Yes
| Updating resources in the cloud. This may take a few minutes...

// 省略

Publish started for S3AndCloudFront
√ Uploaded files successfully.
Your app is published successfully.
http://demo-amplify-js-app-20200415223152-hostingbucket-prod.s3-website-ap-northeast-1.amazonaws.com
```

publishが終了すると自動的にブラウザが起動して公開されたページが表示されます。
![amplify-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/98093e0d-222d-1e24-2b62-2a4d28af7aa7.png)

#### publishで作成されるAWSのリソース

##### S3

公開用のバケットが作成されています。
`demo-amplify-js-app-20200415223152-hostingbucket-prod`
![publish-s3-bucket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/9e4806ff-b5b4-2d40-98f0-0d4feb411b5f.png)
バケットにはwebpackでバンドルされたmain.bundle.jsやindex.htmlがアップロードされています。
![publish-s3-files.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/ced27bb6-780a-73a6-12cc-a02899f2f9c4.png)

##### CloudFormation

Stackが作成されています。
`amplify-demo-amplify-js-app-prod-213624-hostingS3AndCloudFront-13R6I7CHZFCAG`
![publish-cloudformation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/1288e413-28f5-57bf-4cd0-33506f3ee5cf.png)
![publish-cloudformation-resource.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/9ebfbd9b-22c5-d49f-a3c7-431659a4abc4.png)

#### publish後のプロジェクト

`amplify/#current-cloud-backend/hosting`下にファイルが作成されます。
![project-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/758ec4a6-8170-260f-25dc-730e4b9bb1f1.png)

```text
demo-amplify-js-app
  |
  `--- /amplify
  |      |
  |      `--- /.config
  |      |      |
  |      |      `--- ...省略...
  |      |
  |      `--- /#current-cloud-backend
  |      |      |
  |      |      `--- /api
  |      |      |      |
  |      |      |      `--- /todo
  |      |      |             |
  |      |      |             `--- ...省略...
  |      |      |
  |      |      `--- /hosting                        <--- add
  |      |      |      |
  |      |      |      `--- /S3AndCloudFront
  |      |      |             |
  |      |      |             `--- parameters.json
  |      |      |             `--- template.json
  |      |      |
  |      |      `--- amplify-meta.json
  |      |      `--- backend-config.json
  |      |
  |      `--- /backend
  |      |      |
  |      |      `--- /api
  |      |      |      |
  |      |      |      `--- /todo
  |      |      |             |
  |      |      |             `--- ...省略...
  |      |      |
  |      |      `--- /awscloudformation
  |      |      |      |
  |      |      |       `--- nested-cloudformation-stack.yml
  |      |      |
  |      |      `--- /hosting
  |      |      |      |
  |      |      |      `--- /S3AndCloudFront
  |      |      |             |
  |      |      |             `--- parameters.json
  |      |      |             `--- template.json
  |      |      |
  |      |      `--- amplify-meta.json
  |      |      `--- backend-config.json
  |      |
  |      `--- teram-provider-info.json
  |
  `--- /dist
  `--- /node_modules
  `--- /src
  |     |
  |     `--- /graphql
  |     |      |
  |     |      `--- mutations.js
  |     |      `--- queries.js
  |     |      `--- schema.json
  |     |      `--- subscrptions.js
  |     `--- app.js
  |     `--- aws-exports.js
  |
  `--- .gitignore
  `--- .graphqlconfig.yml
  `--- index.html
  `--- package.json
  `--- package-lock.json
  `--- webpack.config.js
```

#### publish後のステータス

下記がpublish後のステータスです。

```console
> amplify status

Current Environment: prod

| Category | Resource name   | Operation | Provider plugin   |
| -------- | --------------- | --------- | ----------------- |
| Api      | todo            | No Change | awscloudformation |
| Hosting  | S3AndCloudFront | No Change | awscloudformation |

GraphQL endpoint: https://xxxxxxxxxxxxxxxxxxxxxxxxxx.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: xxx-xxxxxxxxxxxxxxxxxxxxxxxxxx
Hosting endpoint: http://demo-amplify-js-app-20200415223152-hostingbucket-prod.s3-website-ap-northeast-1.amazonaws.com
```

以上でJavaScriptを利用したWebアプリケーションの”Getting Started”は完了です。

## アプリケーションの修正

### フロント側のコード修正

index.htmlやjsファイルなどフロント側のコードの修正だけであれば、`npm run build`でビルドした後に`amplify publish`コマンドでAWS上のS3へ反映させることができます。

```console
> amplify publish
```

### GraphQLのスキーマの修正 (バックエンド側のコード修正）

Todoオブジェクトに`priority`というフィールドを追加する場合、`amplify/backend/api/todo`のschema.graphqlを以下のように修正します。
ちなみに名前が!で終わっているフィールドは必須フィールドです。

```graphql:schema.graphql
type Todo @model {
  id: ID!
  name: String!
  priority: Int!
  description: String
}
```

ステータスを確認するとApiのOperationが`Update`に変わっています。

```console
> amplify status

Current Environment: prod

| Category | Resource name   | Operation | Provider plugin   |
| -------- | --------------- | --------- | ----------------- |
| Api      | todo            | Update    | awscloudformation |
| Hosting  | S3AndCloudFront | No Change | awscloudformation |

GraphQL endpoint: https://xxxxxxxxxxxxxxxxxxxxxxxxxx.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: xxx-xxxxxxxxxxxxxxxxxxxxxxxxxx
Hosting endpoint: http://demo-amplify-js-app-20200416174831-hostingbucket-prod.s3-website-ap-northeast-1.amazonaws.com
```

Todoオブジェクトの修正を反映するために`amplify push`コマンドを実行します。
途中でGraphQL statements (queries, mutations and subscription)を更新するか聞かれるので`Yes`と入力してコードを生成します。

```console
> amplify push

√ Successfully pulled backend environment prod from the cloud.

Current Environment: prod

| Category | Resource name   | Operation | Provider plugin   |
| -------- | --------------- | --------- | ----------------- |
| Api      | todo            | Update    | awscloudformation |
| Hosting  | S3AndCloudFront | No Change | awscloudformation |
? Are you sure you want to continue? Yes

The following types do not have '@auth' enabled. Consider using @auth with @model
         - Todo
Learn more about @auth here: https://aws-amplify.github.io/docs/cli-toolchain/graphql#auth


GraphQL schema compiled successfully.
Edit your schema at D:\dev\vsc-workspace\demo-amplify-js-app\amplify\backend\api\todo\schema.graphql or place .graphql files in a directory at D:\dev\vsc-worksp
ace\demo-amplify-js-app\amplify\backend\api\todo\schema
? Do you want to update code for your updated GraphQL API Yes
? Do you want to generate GraphQL statements (queries, mutations and subscription) based on your schema types?
This will overwrite your current graphql queries, mutations and subscriptions Yes
/ Updating resources in the cloud. This may take a few minutes...

// 省略

√ Generated GraphQL operations successfully and saved at src\graphql
√ All resources are updated in the cloud

GraphQL endpoint: https://xxxxxxxxxxxxxxxxxxxxxxxxxx.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: xxx-xxxxxxxxxxxxxxxxxxxxxxxxxx
```

バックエンドの修正が終わったら、影響を受けるフロントエンドのソースコード(src/app.js)を、たとえば新規データを登録するコードを以下のように修正します。

```javascript
const todo = { name: "Use AppSync", description: "Realtime and Offline", priority: 1 }
API.graphql(graphqlOperation(createTodo, { input: todo }))
```

ローカルで動作確認をして問題なければ、最終的に`amplify publish`コマンドで公開します。

### source-mapの追加

webpack.config.jsに以下の行を追加します。

```js
module.exports = {

  devtool: 'source-map',

};
```

## アプリケーションの削除

ここまで行うとAWS上にS3、AppSync、DynamoDBなど課金が発生するサービスを利用しています。アプリケーションが不要になったら無駄な課金が発生しないように削除しておきます。

### amplify delete

> Deletes all of the resources tied to the project from the cloud.
> \--------------------------------------------------------------
> プロジェクトに関連付けられているすべてのリソースをクラウドから削除します。

`amplify delete`コマンドでプロジェクトに関連するリソースを削除します。これまでの操作で作成したリソースのほぼすべてを削除してくれますが、静的Webサイト用に作成されたS3バケットだけは残っているので別途AWSコンソールから削除しておきます。

```console
> amplify delete

Scanning for plugins...
Plugin scan successful
? Are you sure you want to continue? (This would delete all the environments of the project from the cloud and wipe out all the local amplify resource files) Yes
- Deleting resources from the cloud. This may take a few minutes...
Deleting env:prod
√ Project deleted in the cloud
Project deleted locally.
```

#### delete後のプロジェクト

`delete`コマンドを実行してもローカルのプロジェクトファイルの大半は残っています。

```text
demo-amplify-js-app
  |
  `--- /dist
  `--- /node_modules
  `--- /src
  |     |
  |     `--- /graphql
  |     |      `--- schema.json
  |     `--- app.js
  |
  `--- .gitignore
  `--- .graphqlconfig.yml
  `--- index.html
  `--- package.json
  `--- package-lock.json
  `--- webpack.config.js
```

# 補足

## consoleコマンド

ブラウザが立ち上がりAmplifyコンソールを表示します。

```console
> amplify console
```

## helpコマンド

`help`コマンド

```console
> amplify help
```

```console
> amplify <command> help
```

### カテゴリ一覧

|カテゴリ       |APIガイド |
|:-------------|:------|
|analytics     |https://aws-amplify.github.io/docs/js/analytics |
|api           |https://aws-amplify.github.io/docs/js/api |
|auth          |https://aws-amplify.github.io/docs/js/authentication |
|function      |       |
|hosting       |       |
|interactions  |https://aws-amplify.github.io/docs/js/interactions |
|notifications |https://aws-amplify.github.io/docs/js/push-notifications |
|predictions   |https://aws-amplify.github.io/docs/js/predictions |
|storage       |https://aws-amplify.github.io/docs/js/storage |
|xr            |https://aws-amplify.github.io/docs/js/xr |

### コマンド一覧

|コマンド            |説明            |
|:------------------|:---------------|
|init               |Initializes a new project, sets up deployment resources in the cloud, and makes your project ready for Amplify.<br>新しいプロジェクトを初期化し、クラウドにデプロイリソースを設定して、プロジェクトをAmplifyに対応させます。|
|configure          |Configures the attributes of your project for amplify-cli, such as switching front-end framework and adding/removing cloud-provider plugins.<br>フロントエンドフレームワークの切り替えやクラウドプロバイダープラグインの追加/削除など、amplify-cliのプロジェクトの属性を構成します。|
|push               |Provisions cloud resources with the latest local developments.<br>最新のローカル開発でクラウドリソースをプロビジョニングします。|
|pull               |Fetch upstream backend environment definition changes from the cloud and updates the local environment to match that definition.<br>クラウドからアップストリームバックエンド環境定義の変更をフェッチし、その定義に一致するようにローカル環境を更新します。|
|publish            |Executes amplify push, and then builds and publishes client-side application for hosting.<br>amplify pushを実行してから、ホスティング用のクライアント側アプリケーションを構築して公開します。|
|serve              |Executes amplify push, and then executes the project's start command to test run the client-side application locally.<br>amplify pushを実行し、プロジェクトの開始コマンドを実行して、クライアント側アプリケーションをローカルでテスト実行します。|
|status             |Shows the state of local resources not yet pushed to the cloud (Create/Update/Delete).<br>まだクラウドにプッシュされていないローカルリソースの状態を表示します（作成/更新/削除）。|
|delete             |Deletes all of the resources tied to the project from the cloud.<br>プロジェクトに関連付けられているすべてのリソースをクラウドから削除します。|
|\<category\> add   |Adds a resource for an Amplify category in your local backend.<br>ローカルバックエンドのAmplifyカテゴリのリソースを追加します。|
|\<category\> update|Update resource for an Amplify category in your local backend.<br>ローカルバックエンドのAmplifyカテゴリのリソースを更新します。|
|\<category\> push  |Provisions all cloud resources in a category with the latest local developments.<br>カテゴリ内のすべてのクラウドリソースを最新のローカル開発でプロビジョニングします。|
|\<category\> remove|Removes a resource for an Amplify category in your local backend.<br>ローカルバックエンドのAmplifyカテゴリのリソースを削除します。|
|\<category\>       |Displays subcommands of the specified Amplify category.<br>指定したamplifyカテゴリのサブコマンドを表示します。|
|mock               |Run mock server for testing categories locally.<br>ローカルでテストカテゴリのモックサーバーを実行します。|
|codegen            |Generates GraphQL statements(queries, mutations and eventHandlers) and type annotations.<br>GraphQLステートメント（queries, mutations and eventHandlers）とtype annotationsを生成します。|
|env                |Displays and manages environment related information for your Amplify project.<br>Amplifyプロジェクトの環境関連情報を表示および管理します。|
|console            |Opens the web console for the selected cloud resource.<br>選択したAWSリソースのWebコンソールを開きます。|

### サブコマンド

**mock**

* storage
* api
* function \<name\>

**env**

* add
* pull [--restore]
* list [--details] [--json]
* get --name \<env-name\> [--json]
* import --name \<env-name\> --config \<provider-configs\> [--awsinfo \<aws-configs\>]
* remove \<env-name\>

## 対話形式の選択肢

amplifyコマンドの選択肢の内容について補足します。

### amplify init

**Choose your default editor**
デフォルトのエディターを選択
![choose-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/5548f39c-73de-f1dd-8486-8c0ca3f17876.png)
**Choose the type of app that you're building**
構築するアプリのタイプを選択します
![choose-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/70a8170f-2ee8-14f2-c046-3dc1b756bbff.png)
**What javascript framework are you using**
どのJavaScriptフレームワークを使用するか
![choose-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/00ced01f-7021-39dc-788c-315904b80742.png)

### amplify add api

**Please select from one of the below mentioned services**
以下のサービスのいずれかから選択してください
![choose-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/21c271c5-91ec-36d3-f7b4-2c683b643147.png)
**Choose the default authorization type for the API**
APIのデフォルトの認証タイプを選択します
![choose-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/075e7aa8-1f41-c579-90dc-617091c13745.png)
**Do you want to configure advanced settings for the GraphQL API**
GraphQL APIの詳細設定を構成しますか？
![choose-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/e6569cbf-23c6-c905-fb04-c7c0979bfd02.png)
**What best describes your project**
プロジェクトを最もよく表すもの
![choose-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/c2960ec8-90d7-2c03-1974-4da6fe0c3cac.png)

### amplify push

**Choose the code generation language target**
生成するコードの言語を選択してください
![choose-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/40d4f0b5-1954-8ce1-f20d-a676c082cb82.png)

### amplify add hosting

**Select the plugin module to execute**
実行するプラグインモジュールを選択します
![choose-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/4c239ddf-fe59-d023-cd98-324aec34f6c3.png)
**Select the environment setup**
環境設定を選択
![choose-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/074b32d7-3c13-9c5f-303d-f6d39c20ddcc.png)