APIとデータベースをアプリに接続する
アプリケーションを作成および設定し、新しいAmplifyプロジェクトを初期化したので、機能を追加できます。最初に追加する機能はAPIです。
Amplify CLIはAPIカテゴリーの2つのタイプ、RESTとGraphQLの作成と相互作用をサポートしています。
このステップで作成するAPIは、AWS AppSync(マネージドGraphQLサービス)を使用するGraphQL APIであり、データベースはAmazon DynamoDB(NoSQLデータベース)になります。
GraphQL APIとデータベースを作成する
以下のコマンドを実行して、GraphQL APIをアプリに追加し、データベースを自動的にプロビジョニングします。アプリケーションディレクトリのルートから実行します:
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)CLIはこのGraphQLスキーマをテキストエディタで開くよう促します。
amplify/backend/api/your-api-name/schema.graphql
# 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/react/build-a-backend/graphqlapi/customize-authorization-rules/
input AMPLIFY { globalAuthRule: AuthRule = { allow: public }} # FOR TESTING ONLY!type Todo @model { id: ID! name: String! description: String}生成されたスキーマはTodoアプリ用です。Todoタイプの@modelディレクティブに気付くでしょう。このディレクティブはAmplify GraphQL APIカテゴリーの一部です。
Amplify GraphQL APIは、カスタムGraphQLディレクティブを提供し、データモデルを定義、認可ルールを設定、サーバーレス関数をリゾルバーとして構成するなど、さらに多くのことができます。
@modelディレクティブで装飾されたGraphQLタイプは、タイプ(Todoテーブル)のデータベーステーブル、CRUD(作成、読み取り、更新、削除)およびリスト操作のスキーマ、そしてすべてを一緒に機能させるために必要なGraphQLリゾルバーをスキャフォールディングします。
コマンドラインからEnterキーを押してスキーマを受け入れ、次のステップに進みます。
APIをデプロイする
このバックエンドをデプロイするには、pushコマンドを実行します:
amplify push各プロンプトに対して以下の値を選択します:
✔ Are you sure you want to continue? (Y/n) · yes...? Do you want to generate code for your newly created GraphQL API: Yes? Choose the code generation language target: typescript? Enter the file name pattern of graphql queries, mutations and subscriptions: src/graphql/**/*.ts? 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? Enter the file name for the generated code: src/API.ts✔ Are you sure you want to continue? (Y/n) · 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? Enter the file name for the generated code src/API.jsAPIはライブになり、相互作用を開始できます。デプロイしたAPIには、投稿を作成、読み取り、更新、削除、および一覧表示するための操作が含まれています。
デプロイメントステータスを確認する
次に、以下のコマンドを実行してAmplifyのステータスを確認します:
amplify statusこれはAmplifyプロジェクトの現在のステータスを表示します。現在の環境、作成されたカテゴリー、およびそれらのカテゴリーの状態が含まれます。以下のようになります:
Current Environment: dev
┌──────────┬───────────────────────┬───────────┬───────────────────┐│ Category │ Resource name │ Operation │ Provider plugin │├──────────┼───────────────────────┼───────────┼───────────────────┤│ Api │ your-api-name │ No Change │ awscloudformation │└──────────┴───────────────────────┴───────────┴───────────────────┘AWSコンソールでデプロイされたAPIを確認する
AppSyncコンソールでGraphQL APIを任意の時点で表示するには、以下のコマンドを実行します:
amplify console apiAmplifyコンソールでアプリ全体を任意の時点で表示するには、以下のコマンドを実行します:
amplify consoleローカルモッキングでAPIをテストする
これをローカルでテストするには、mockコマンドを実行できます。注:モッキングをセットアップするための指示を参照してください。
フロントエンドを接続して先に進みたい場合は、次のステップにスキップできます。
amplify mock api注: amplify mock apiにはJavaが必要です。
# If you have not already deployed your API, you will be walked through the following steps for GraphQL code generation? Choose the code generation language target: javascript (or preferred target)? 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これにより、ローカルポートでGraphiQLエクスプローラーが開きます。テスト環境から、クエリやミューテーションなど、さまざまな操作をローカルで試すことができます。
GraphiQLツールバーで、Use: User Poolを選択し、Todoを作成してみてください:
mutation CreateTodo { createTodo(input: { name: "Test Todo", description: "Todo description" }) { id owner name updatedAt createdAt description }}次に、認証をUse: API Keyに更新し、Todoのリストをクエリしてみてください:
query ListTodos { listTodos { items { description createdAt id owner name } }}フロントエンドをAPIに接続する
このセクションでは、React アプリケーションからTodoを一覧表示および作成する方法を作成します。これを行うには、Todoを作成するボタン付きのフォームを作成し、Todoのリストをフェッチしてレンダリングする方法も作成します。
App.jsを開き、次のコードで置き換えます:
import React, { useEffect, useState } from 'react';import { StyleSheet, Text, View, TextInput, Pressable, SafeAreaView} from 'react-native';import { generateClient } from 'aws-amplify/api';import { createTodo } from './src/graphql/mutations';import { listTodos } from './src/graphql/queries';
import { Amplify } from 'aws-amplify';import amplifyconfig from './src/amplifyconfiguration.json';Amplify.configure(amplifyconfig);
const initialState = { name: '', description: '' };const client = generateClient();
const App = () => { const [formState, setFormState] = useState(initialState); const [todos, setTodos] = useState([]);
useEffect(() => { fetchTodos(); }, []);
function setInput(key, value) { setFormState({ ...formState, [key]: value }); }
async function fetchTodos() { try { const todoData = await client.graphql({ query: listTodos }); const todos = todoData.data.listTodos.items; setTodos(todos); } catch (err) { console.log('error fetching todos'); } }
async function addTodo() { try { if (!formState.name || !formState.description) return; const todo = { ...formState }; setTodos([...todos, todo]); setFormState(initialState); await client.graphql({ query: createTodo, variables: { input: todo } }); } catch (err) { console.log('error creating todo:', err); } }
return ( <SafeAreaView style={styles.container}> <View style={styles.container}> <TextInput onChangeText={(value) => setInput('name', value)} style={styles.input} value={formState.name} placeholder="Name" /> <TextInput onChangeText={(value) => setInput('description', value)} style={styles.input} value={formState.description} placeholder="Description" /> <Pressable onPress={addTodo} style={styles.buttonContainer}> <Text style={styles.buttonText}>Create todo</Text> </Pressable> {todos.map((todo, index) => ( <View key={todo.id ? todo.id : index} style={styles.todo}> <Text style={styles.todoName}>{todo.name}</Text> <Text style={styles.todoDescription}>{todo.description}</Text> </View> ))} </View> </SafeAreaView> );};
export default App;
const styles = StyleSheet.create({ container: { width: 400, flex: 1, padding: 20, alignSelf: 'center' }, todo: { marginBottom: 15 }, input: { backgroundColor: '#ddd', marginBottom: 10, padding: 8, fontSize: 18 }, todoName: { fontSize: 20, fontWeight: 'bold' }, buttonContainer: { alignSelf: 'center', backgroundColor: 'black', paddingHorizontal: 8 }, buttonText: { color: 'white', padding: 16, fontSize: 18 }});App.tsxを開き、次のコードで置き換えます:
import React, { useEffect, useState } from 'react';import { StyleSheet, Text, View, TextInput, Pressable, SafeAreaView} from 'react-native';import { generateClient } from 'aws-amplify/api';import { createTodo } from './src/graphql/mutations';import { listTodos } from './src/graphql/queries';
const initialState = { name: '', description: '' };const client = generateClient();
const App = () => { const [formState, setFormState] = useState(initialState); const [todos, setTodos] = useState([]);
useEffect(() => { fetchTodos(); }, []);
function setInput(key, value) { setFormState({ ...formState, [key]: value }); }
async function fetchTodos() { try { const todoData = await client.graphql({ query: listTodos }); const todos = todoData.data.listTodos.items; setTodos(todos); } catch (err) { console.log('error fetching todos'); } }
async function addTodo() { try { if (!formState.name || !formState.description) return; const todo = { ...formState }; setTodos([...todos, todo]); setFormState(initialState); await client.graphql({ query: createTodo, variables: { input: todo } }); } catch (err) { console.log('error creating todo:', err); } }
return ( <SafeAreaView style={styles.container}> <View style={styles.container}> <TextInput onChangeText={(value) => setInput('name', value)} style={styles.input} value={formState.name} placeholder="Name" /> <TextInput onChangeText={(value) => setInput('description', value)} style={styles.input} value={formState.description} placeholder="Description" /> <Pressable onPress={addTodo} style={styles.buttonContainer}> <Text style={styles.buttonText}>Create todo</Text> </Pressable> {todos.map((todo, index) => ( <View key={todo.id ? todo.id : index} style={styles.todo}> <Text style={styles.todoName}>{todo.name}</Text> <Text style={styles.todoDescription}>{todo.description}</Text> </View> ))} </View> </SafeAreaView> );};
export default App;
const styles = StyleSheet.create({ container: { width: 400, flex: 1, padding: 20, alignSelf: 'center' }, todo: { marginBottom: 15 }, input: { backgroundColor: '#ddd', marginBottom: 10, padding: 8, fontSize: 18 }, todoName: { fontSize: 20, fontWeight: 'bold' }, buttonContainer: { alignSelf: 'center', backgroundColor: 'black', paddingHorizontal: 8 }, buttonText: { color: 'white', padding: 16, fontSize: 18 }});いくつかの関数を説明しましょう:
useEffect - コンポーネントがレンダリングされた後、useEffectフックが呼び出され、fetchTodos関数が起動されます。
fetchTodos - generateClient()で作成されたAmplify API clientを使用してAppSync GraphQL APIをlistTodosクエリで呼び出します。データが返されたら、itemsアレイがsetTodos関数に渡されてローカル状態を更新します。
addTodo - generateClient()で作成されたAmplify API clientを使用してAppSync GraphQL APIをcreateTodoミューテーションで呼び出します。listTodosクエリとcreateTodoミューテーションの違いは、createTodoがミューテーションに必要な変数を含む引数を受け入れることです。
ローカルで実行する
次に、アプリを実行して、Todoを作成および表示する機能を備えた更新されたUIが表示されることを確認します:
以下のコマンドでアプリを起動します:
Android の場合:
npx expo run:androidiOS の場合:
npx expo run:iosnpm startAPIを正常にデプロイし、アプリに接続しました。