在 Amazon Amplify 上部署 Web 應用程式

入門指南

單元 2:建置前端和連接 API

在此單元中,您將了解如何將 API 新增至 Amplify 專案

簡介

在此單元中,您將建置 Web 應用程式的前端,並使用 GraphQL API 連接至 API (應用程式介面)。GraphQL 是一種 API 查詢語言,可協助您擷取和更新應用程式上的資料。

您將學到的內容

  • 建立基本 React 前端應用程式
  • 從您的應用程式呼叫 GraphQL API
  • 從應用程式前端呼叫 API

 完成時間

10 分鐘

 單元先決條件

  • 有管理員等級存取權限的 AWS 帳戶**
  • 建議的瀏覽器:最新版的 Chrome 或 Firefox

[**]過去 24 小時內建立的帳戶可能尚未有權存取本教學課程所需的服務。

實作

安裝 Amplify 程式庫

您必須安裝 Amplify React 程式庫 @aws-amplify/ui-react (包含 React UI 元件)。 

執行下列命令加以安裝:

npm install @aws-amplify/ui-react

現在,您必須建立應用程式的前端。開啟 src/App.js 檔案,並將其內容取代為下列程式碼:

import { withAuthenticator, AmplifySignOut } from '@aws-amplify/ui-react';
import Amplify from 'aws-amplify';
import awsExports from './aws-exports';

Amplify.configure(awsExports);

function App() {
  return (
    <div>
      <h1>Notes App</h1>
      <AmplifySignOut />
    </div>
  );
}

export default withAuthenticator(App);

測試應用程式

現在您可以在本機執行應用程式,加以測試:

npm start

這會在 http://localhost:3000 上啟動開發伺服器,並在您的瀏覽器中開啟頁面。系統會提示您必須先註冊才可使用服務 - 這項資料會儲存在您專案的 Congnito 資料庫中,且只有您可加以存取。在登入後,應用程式將只會顯示含有備註應用程式的標題,和一個登入按鈕,因為您尚未新增任何項目。接著,您將在應用程式中新增 API。您可以使用 ctrl + c 再次停止伺服器。

gsg-build-amplify-2

使用幾個 CLI 命令和幾行程式碼,我們就已建立具有登入流程的有效單頁應用程式。此應用程式只是框架,且登入尚無法運作。請在以下幾節繼續將功能新增至您的應用程式。

使用 Amplify 新增 GraphQL API

現在,您要將 API 新增至應用程式。Amplify 會使用 AWS AppSync 和 Amazon DynamoDB 為 GraphQL API 提供技術支援。AppSync 是一個負責處理 API 的受管 GraphQL 服務,而 Amazon DynamoDB 則是一個 NoSQL 資料庫,將存放我們的 API 所將使用的資料。

若要新增 API,請執行 amplify add api,並選擇下列問題選項 (以 > 符號開頭的幾行) - 在此步驟中,系統會詢問關於授權供應商的問題,而後續的指南將會用到這項資料:

GraphQL 結構描述表示物件及其欄位。您必須定義您的 GraphQL 結構描述,而 Amplify 將會建立必要的 DynamoDB 資料表,並設定 GraphQL 為您處理讀取、寫入、更新和刪除。開啟 amplify/backend/api/amplifyapp/schema.graphql 檔案,並將其內容取代為:

amplify add api

? Please select from one of the below mentioned services:
❯ GraphQL
  REST
? Provide API name: amplifyapp
? Choose the default authorization type for the API
  API key
❯ Amazon Cognito User Pool
  IAM
  OpenID Connect
? Do you want to configure advanced settings for the GraphQL API
? Do you want to use the default authentication and security configuration?
❯ Default configuration
  Default configuration with Social Provider (Federation)
  Manual configuration
  I want to learn more.
? How do you want users to be able to sign in?
 ◯ Email
❯◉ Username
 ◯ Phone number
? Do you want to configure advanced settings?
❯ No, I am done.
  Yes, I want to make some additional changes.
? Do you have an annotated GraphQL schema? No
? Choose a schema template:
❯ Single object with fields (e.g., “Todo” with ID, name, description)
  One-to-many relationship (e.g., “Blogs” with “Posts” and “Comments”)
  Objects with fine-grained access control (e.g., a project management app with owner-bas
ed authorization)
? Do you want to edit the schema now? Yes
如果您輸入 Yes 以立即編輯結構描述,您的預設編輯器應在開啟後顯示下一節需要的檔案。

建立 GraphQL 結構描述

GraphQL 結構描述表示物件及其欄位。您必須定義您的 GraphQL 結構描述,而 Amplify 將會建立必要的 DynamoDB 資料表,並設定 GraphQL 為您處理讀取、寫入、更新和刪除。開啟 amplify/backend/api/amplifyapp/schema.graphql 檔案,並將其內容取代為:

type Note @model @auth(rules: [{ allow: owner }]) {
  id: ID!
  text: String!
}

此結構描述會將備註類型及其 ID 和文字定義為必要欄位。此外也會包含 Amplify 的 GraphQL Transform 程式庫中的指示詞:

@model:加註 @model 的類型會存放在 DynamoDB 中,且系統會自動為其建立 CRUDL (建立、讀取、更新、刪除、列出) 作業。

@auth:加註 @auth 的類型會受到一組授權規則的保護。在此,我們使用擁有者授權來確保只有備註的擁有者才可存取和修改備註。

部署應用程式

您現在已準備就緒,可藉由執行 amplify push 來部署 Amplify Web 應用程式。這會為您將應用程式上傳至 AWS 帳戶,且 Amplify 會顯示正在部署的變更,並要求您確認該部署:

✔ Successfully pulled backend environment dev from the cloud.

Current Environment: dev
    
┌──────────┬────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name      │ Operation │ Provider plugin   │
├──────────┼────────────────────┼───────────┼───────────────────┤
│ Auth     │ amplifyapp6177aede │ Create    │ awscloudformation │
├──────────┼────────────────────┼───────────┼───────────────────┤
│ Api      │ amplifyapp         │ 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

此部署需要幾分鐘的時間,且您會看到正在為您建立的資源清單。Amplify 執行了下列動作:

  • 建立由 AWS AppSync 提供技術支援的 GraphQL API,且三種類型的 GraphQL 作業皆齊備 (查詢、變動和訂閱)。
  • 使用建立、擷取和更新備註所需的 GraphQL 作業,在 src/graphql/ 資料夾內產生程式碼。
  • 建立 DynamoDB 資料表,以存放任何用我們的應用程式建立的備註

更新前端以使用 API

若要使用您剛部署的新 API,請將 src/App.js 檔案的內容取代為下列程式碼,加以更新:

import { Component } from 'react';
import Amplify, { API, graphqlOperation } from 'aws-amplify';
import { createNote, deleteNote } from './graphql/mutations';
import { listNotes } from './graphql/queries';

import { withAuthenticator, AmplifySignOut } from '@aws-amplify/ui-react';
import awsExports from './aws-exports';

Amplify.configure(awsExports);

class AddNote extends Component {
  constructor(props) {
    super(props);
    this.state = { text: '' };
  }

  handleChange = (event) => {
    this.setState({ text: event.target.value });
  }

  handleClick = () => {
    this.props.addNote(this.state);
    this.setState({ text: '' });
  }

  render() {
    return (
      <div style={styles.form}>
        <input
          value={this.state.text}
          onChange={this.handleChange}
          placeholder="New Note"
          style={styles.input}
        />
        <button onClick={this.handleClick} style={styles.addButton}>Add Note</button>
      </div>
    );
  }
}

class NotesList extends Component {
  render() {
    return (
      <div>
        {this.props.notes.map(note =>
          <div key={note.id} style={styles.note}>
            <p>{note.text}</p>
            <button onClick={() => { this.props.deleteNote(note) }} style={styles.deleteButton}>x</button>
          </div>
        )}
      </div>
    );
  }
}

class App extends Component {
  constructor(props) {
    super(props);
    this.state = { notes: [] };
  }

  async componentDidMount() {
    var result = await API.graphql(graphqlOperation(listNotes));
    this.setState({ notes: result.data.listNotes.items });
  }

  deleteNote = async (note) => {
    const id = {
      id: note.id
    };
    await API.graphql(graphqlOperation(deleteNote, { input: id }));
    this.setState({ notes: this.state.notes.filter(item => item.id !== note.id) });
  }

  addNote = async (note) => {
    var result = await API.graphql(graphqlOperation(createNote, { input: note }));
    this.state.notes.push(result.data.createNote);
    this.setState({ notes: this.state.notes });
  }

  render() {
    return (
      <div style={styles.container}>
        <h1>Notes App</h1>
        <AddNote addNote={this.addNote} />
        <NotesList notes={this.state.notes} deleteNote={this.deleteNote} />
        <AmplifySignOut />
      </div>
    );
  }
}

export default withAuthenticator(App);

const styles = {
  container: { width: 480, margin: '0 auto', padding: 20 },
  form: { display: 'flex', marginBottom: 15 },
  input: { flexGrow: 2, border: 'none', backgroundColor: '#ddd', padding: 12, fontSize: 18 },
  addButton: { backgroundColor: 'black', color: 'white', outline: 'none', padding: 12, fontSize: 18 },
  note: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: 22, marginBottom: 15 },
  deleteButton: { fontSize: 18, fontWeight: 'bold' }
}

現在,您已有可運作的應用程式。現在,只要使用多重要素驗證登入,應用程式即可與 API 通訊以儲存/更新/刪除備註。若要在本機加以測試,請再次執行 npm start 進行確認。

gsg-build-amplify-3

結論

在本單元中,您已了解如何建立 React 前端應用程式、為其新增 API,並將 API 部署至您的 AWS 帳戶。在下一個單元中,您將了解如何從 GitHub 儲存庫部署前端,並設定 CI/CD 管道用以自動部署未來的變更。

下一步:自動化部署

讓我們知道我們表現如何。

感謝您的意見回饋
我們很高興此頁面對您有所幫助。您願意分享更多詳細資訊以協助我們繼續改進嗎?
關閉
感謝您的意見回饋
很抱歉此頁面沒有幫助到您。您願意分享更多詳細資訊以協助我們繼續改進嗎?
關閉