LoginSignup
5
9

More than 3 years have passed since last update.

2019年12月版 AWS Amplify + AppSync + Cloud9 + React.js でとりあえず動くまでの手順

Last updated at Posted at 2019-12-23

目的

  1. Cloud9上での aws amplify, aws appsync を利用する開発環境の構築
  2. React上での subscription による リアルタイムデータ配信アプリの構築
  3. amplify の機能による S3+CloudFlont でのアプリのデプロイ
Vue.js バージョンはこちら

前提

  1. 利用するリージョンは ap-northeast-1
  2. CodeCommitのリポジトリ名は amplify_test_react
  3. amplifyで利用するiamユーザは amplify-test-user
  4. アプリ名はmytodo
  5. api名はmytodoapi

注意

この投稿は @aws_amplify/api, @aws_amplify/pubsub パッケージを利用しています。
2019年12月では、aws_amplify, aws_amplify_react パッケージと同時に利用することはできません。
AWSKinesisFirehoseProvider.js あたりでエラーが発生する場合はパッケージの混同を疑ってみてください。

構築手順


  1. CodeCommitへのGitリポジトリ作成

    * 'amplify_test_react'を使用

  2. Cloud9の開発環境作成

    * aws consoleで作成

  3. Cloud9の一時認証の利用を解除

    1. ツールバーのAWS Cloud9でメニューを開く
    2. Preferencesを開く
    3. AWS SETTINGSを開く
    4. Credentialsを開く
    5. AWS managed temporary credentials をオフにする

  4. 開発環境とGitリポジトリの連携
    $ git clone ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/amplify_test_react
    

  5. nodeのインストール
    最新、または、好みのバージョンを確認
    $ nvm ls-remote
    

    指定したバージョンでインストールを実行

    $ nvm install 指定のバージョン
    

  6. aws amplify cli のインストール
    $ npm install -g @aws-amplify/cli
    

  7. amplify の初期設定
    1. configureを実行
      $ amplify configure
      

    2. 管理者アカウントでaws consoleをブラウザで開く
      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
      

    3. 利用するリージョンを選択、ユーザ名を入力

      出力されたurlをaws cosoleを開けたブラウザで開いてユーザを作成

      デフォルトの値は入っているので作成を完了するだけ
      Specify the AWS Region
      ? region:  ap-northeast-1
      Specify the username of the new IAM user:
      ? user name:  amplify-test-user
      Complete the user creation using the AWS console
      https://console.aws.amazon.com/iam/home?region=undefined#/users$new?step=final&accessKey&userNames=amplify-test-user&permissionType=policies&policies=arn:aws:iam::aws:policy%2FAdministratorAccess
      Press Enter to continue
      

    4. ユーザ作成で得ることのできた accessKeyId と secretAccessKey を入力
      Enter the access key of the newly created user:
      ? accessKeyId:  ********************
      ? secretAccessKey:  ****************************************
      This would update/create the AWS Profile in your local machine
      ? Profile Name:  default
      
      Successfully set up the new user.
      

  8. react のインストールとプロジェクトの作成
    $ npx create-react-app mytodo
    $ cd mytodo
    

  9. アプリケーションを実行して確認
    $ npm start
    

    メニューの Preview -> Preview Running Application を実行

    Cloud9内のブラウザでReactのセットアップが完了していることを確認

  10. SecurityErrorが表示される場合

    以下のエラーが表示される場合は、React Scriptの問題

    SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
    

    対応するには React Script 3.3.0 を利用しないようにする

    以下の通り React Script 3.2.0 を利用するにうにpackage.jsonを修正してインストールする

    package.json
    - "react-scripts": "3.3.0"
    + "react-scripts": "3.2.0"
    

    参考: create-react-appで作ったアプリがhttpsだと動かない

  11. aws-amplify をインストール
    $ npm install @aws-amplify/api
    $ npm install @aws-amplify/pubsub
    $ npm install aws-amplify-react
    

  12. amplify の初期設定
    $ amplify init
    
    Note: It is recommended to run this command from the root of your app directory
    ? Enter a name for the project mytodo
    ? Enter a name for the environment dev
    ? Choose your default editor: Vim (via Terminal, Mac OS only)
    ? Choose the type of app that you're building javascript
    Please tell us about your project
    ? What javascript framework are you using react
    ? Source Directory Path:  src
    ? Distribution Directory Path: build
    ? Build Command:  npm run-script build
    ? Start Command: npm run-script start
    

  13. amplify の初期設定確認
    $ amplify status
    
    Current Environment: dev
    
    | Category | Resource name | Operation | Provider plugin |
    | -------- | ------------- | --------- | --------------- |
    

  14. api の追加準備
    $ amplify add api
    
    ? Please select from one of the below mentioned services: GraphQL
    ? Provide API name: mytodoapi
    ? Choose the default authorization type for the API API key
    ? Enter a description for the API key: 
    ? After how many days from now the API key should expire (1-365): 365
    ? 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
    

  15. api の追加内容確認
    $ amplify status
    
    Current Environment: dev
    
    | Category | Resource name | Operation | Provider plugin   |
    | -------- | ------------- | --------- | ----------------- |
    | Api      | mytodoapi     | Create    | awscloudformation |
    

  16. バックエンドに api の追加内容を反映
    $ amplify push
    
    Current Environment: dev
    
    | Category | Resource name | Operation | Provider plugin   |
    | -------- | ------------- | --------- | ----------------- |
    | Api      | mytodoapi     | Create    | awscloudformation |
    
    ? Are you sure you want to continue? Yes
    ? 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
    

  17. mytodo を修正

    1. App.js を修正
      App.js
      import React, { useEffect, useReducer } from 'react';
      
      import API, { graphqlOperation } from '@aws-amplify/api';
      import PubSub from '@aws-amplify/pubsub';
      
      import { createTodo } from './graphql/mutations';
      import { listTodos } from './graphql/queries';
      
      import awsconfig from './aws-exports';
      import './App.css';
      
      // Configure Amplify
      API.configure(awsconfig);
      PubSub.configure(awsconfig);
      
      // Action Types
      const QUERY = 'QUERY';
      
      const initialState = {
        todos: [],
      };
      
      const reducer = (state, action) => {
        switch (action.type) {
          case QUERY:
            return {...state, todos: action.todos};
          default:
            return state;
        }
      };
      
      async function createNewTodo() {
        const todo = {
          name: "New Todo Title",
          description: "do something at " + Date()
        }
        await API.graphql(graphqlOperation(createTodo, { input: todo }));
      }
      
      function App() {
        const [state, dispatch] = useReducer(reducer, initialState);
      
        useEffect(() => {
          async function getData() {
            const todoData = await API.graphql(graphqlOperation(listTodos));
            dispatch({ type: QUERY, todos: todoData.data.listTodos.items });
          }
          getData();
        }, []);
      
        return (
          <div>
          <div className="App">
            <button onClick={createNewTodo}>Add Todo</button>
          </div>
          <div>
            {state.todos.length > 0 ? 
              state.todos.map((todo) => <p key={todo.id}>{todo.name} : {todo.description}</p>) :
              <p>Add Todo</p> 
            }
          </div>
        </div>
        );
      }
      
      export default App;
      

    2. 実行してブラウザでTodoが追加されることを確認

      Add Todoボタンをクリックしたあと、リロードすることでTodoが追加されていることが確認できる

  18. subscription を利用してみる

    1. App.js を修正
      App.js
      import React, { useEffect, useReducer } from 'react';
      
      import API, { graphqlOperation } from '@aws-amplify/api';
      import PubSub from '@aws-amplify/pubsub';
      
      import { createTodo } from './graphql/mutations';
      import { listTodos } from './graphql/queries';
      import { onCreateTodo } from './graphql/subscriptions';
      
      import awsconfig from './aws-exports';
      import './App.css';
      
      // Configure Amplify
      API.configure(awsconfig);
      PubSub.configure(awsconfig);
      
      // Action Types
      const QUERY = 'QUERY';
      const SUBSCRIPTION = 'SUBSCRIPTION';
      
      const initialState = {
        todos: [],
      };
      
      const reducer = (state, action) => {
        switch (action.type) {
          case QUERY:
            return {...state, todos: action.todos};
          case SUBSCRIPTION:
            return {...state, todos:[...state.todos, action.todo]};
          default:
            return state;
        }
      };
      
      async function createNewTodo() {
        const todo = {
          name: "New Todo Title",
          description: "do something at " + Date()
        }
        await API.graphql(graphqlOperation(createTodo, { input: todo }));
      }
      
      function App() {
        const [state, dispatch] = useReducer(reducer, initialState);
      
        useEffect(() => {
          async function getData() {
            const todoData = await API.graphql(graphqlOperation(listTodos));
            dispatch({ type: QUERY, todos: todoData.data.listTodos.items });
          }
          getData();
          const subscription = API.graphql(graphqlOperation(onCreateTodo)).subscribe({
              next: (eventData) => {
                const todo = eventData.value.data.onCreateTodo;
                dispatch({ type: SUBSCRIPTION, todo });
              }
            });
      
          return () => subscription.unsubscribe();
        }, []);
      
        return (
          <div>
          <div className="App">
            <button onClick={createNewTodo}>Add Todo</button>
          </div>
          <div>
            {state.todos.length > 0 ? 
              state.todos.map((todo) => <p key={todo.id}>{todo.name} : {todo.description}</p>) :
              <p>Add Todo</p> 
            }
          </div>
        </div>
        );
      }
      
      export default App;
      

    2. 実行して2つのブラウザで同期的にTodoが追加されることを確認

  19. Hosting の準備
    $ amplify add hosting
    
    ? Select the environment setup: DEV (S3 only with HTTP)
    ? hosting bucket name mytodo-20191223025707-hostingbucket
    ? index doc for the website index.html
    ? error doc for the website index.html
    

  20. Hosting の追加内容の確認
    $ amplify status
    
    Current Environment: dev
    
    | Category | Resource name   | Operation | Provider plugin   |
    | -------- | --------------- | --------- | ----------------- |
    | Hosting  | S3AndCloudFront | Create    | awscloudformation |
    | Api      | mytodoapi       | No Change | awscloudformation |
    

  21. バックエンドに Hosting の追加内容を反映
    $ amplify push
    
    Current Environment: dev
    
    | Category | Resource name   | Operation | Provider plugin   |
    | -------- | --------------- | --------- | ----------------- |
    | Hosting  | S3AndCloudFront | Create    | awscloudformation |
    | Api      | mytodoapi       | No Change | awscloudformation |
    ? Are you sure you want to continue? Yes
    

  22. バックエンドの Hosting を公開
    $ amplify publish
    

  23. PublishされたURLを2つのブラウザで開いて同期的にTodoが追加されることを確認

  24. 作成した amplify のリソースを削除
    $ amplify delete
    

    amplify delete した後、再度 amplify init で作成し直す場合は、aws-exports.js ファイルを削除しておく。init や add で更新されない。

    amplify init したアプリを deleteせずに再度initする場合、CloudFormation上から削除できなくなるので、注意。

  25. 参考

    1. 【お手軽ハンズオンで AWS を学ぶ】AWS Amplify で Todo アプリを作ろう! AWS AppSync & Amazon DynamoDB によるリアルタイムメッセージング

    2. AWS Amplify Getting Start

    3. create-react-appで作ったアプリがhttpsだと動かない

5
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
9