在 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 再次停止伺服器。

使用幾個 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
建立 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 進行確認。
