Name:
interface
Value:
Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Page updated Apr 30, 2024

Maintenance ModeYou are viewing Amplify Gen 1 documentation. Amplify Gen 1 has entered maintenance mode and will reach end of life on May 1, 2027. New project should use Amplify Gen 2. For existing Gen 1 projects, a migration guide and tooling are available to help you upgrade. Switch to the latest Gen 2 docs →

アプリケーションデータの読み取り

Amplify GraphQLクライアントを使用してアプリケーションデータを読み取ることができます。このガイドでは、データの読み取りと取得の違い、必要なデータだけを取得するためのクエリ結果のフィルタリング方法、結果をより管理しやすくするためのページネーション方法について説明します。必要に応じてこれらのリクエストをキャンセルする方法も紹介します。

始める前に、以下が必要です:

データのリストと取得

クエリはAPIを通じてデータを読み取るために使用され、listgetの操作が含まれます。

Amplify CLIは、GraphQL APIの@modelタイプに対して、listgetクエリを自動的に作成します。listクエリは、特定のレコードの識別子を指定する必要なく、Todoアイテムなどの複数のアイテムを取得します。これはアイテムの概要またはサマリーを取得するか、list操作を拡張して特定の条件でアイテムをフィルタリングするのに最適です。識別子で単一のエントリをクエリしたい場合は、getを使用して特定のTodoアイテムを取得します。

注: 基盤となるデータソースのコスト構造は、一部のクエリを実行するコストに影響を与える可能性があります。例えば、list操作はAmazon DynamoDB「スキャン操作」を使用し、get操作よりも多くの読み取りリクエストユニットを使用できます。データソースのこれらの操作に関連するコストを確認する必要があります。この例ではDynamoDBを使用しています。DynamoDBのコスト計算方法の詳細については、Amazon DynamoDBの価格設定をご覧ください。

Amplify CLIは、すべての可能なGraphQL操作(ミューテーション、クエリ、サブスクリプション)のGraphQLクライアントコードを自動的に生成します。JavaScriptアプリケーションの場合、生成されたコードはデフォルトでsrc/graphqlフォルダに保存されます。

GraphQLクエリを実行するには、生成されたクエリをインポートして、client.graphqlで実行します:

import { generateClient } from 'aws-amplify/api';
import * as queries from './graphql/queries';
const client = generateClient();
// Simple query
const allTodos = await client.graphql({ query: queries.listTodos });
console.log(allTodos); // result: { "data": { "listTodos": { "items": [/* ..... */] } } }
// Fetch a single record by its identifier
const oneTodo = await client.graphql({
query: queries.getTodo,
variables: { id: 'some id' }
});
トラブルシューティング
未認可エラーのトラブルシューティング

少なくとも1つの認可ルールが定義されていない場合、未認可エラーが発生する可能性があります。

@authディレクティブを使用して、パブリック、サインイン済みユーザー、ユーザーごと、およびユーザーグループごとのデータアクセスの認可ルールを構成します。認可ルールはデフォルトでの拒否の原則に基づいて動作します。つまり、認可ルールが明確に構成されていない場合、それは拒否されます。

type Todo @model @auth(rules: [{ allow: owner }]) {
content: String
}

前の例では、各サインイン済みユーザーまたは「オーナー」がTodoの作成、読み取り、更新、および削除を行うことができます。

Amplifyは、許可されている操作を制限し、複数の認可ルールを組み合わせ、きめ細かいフィールドレベルの認可を適用することも可能にします。

type Todo
@model
@auth(rules: [{ allow: public, operations: [read] }, { allow: owner }]) {
content: String
}

前の例では、すべてのユーザー(public)がすべてのTodoを読み取ることができますが、owner(認証されたユーザー)は自分のTodoの作成、読み取り、更新、および削除ができます。

詳細については、GraphQL APIの認可ルールを参照してください。


詳細
データをクエリするカスタム認可モード

各AWS AppSync APIは、アプリを設定する際にデフォルトの認可モードを使用します。このデフォルトをオーバーライドするには、authModeプロパティを渡します。例えば、API Keyオーサリゼーションによるパブリック読み取りとIAMオーサリゼーションによる認証読み取りがある場合に便利です。次の例は、カスタム認可モードでデータをクエリする方法を示しています:

import { generateClient } from 'aws-amplify/api';
import * as queries from './graphql/queries';
const client = generateClient();
const todos = await client.graphql({
query: queries.listTodos,
authMode: GRAPHQL_AUTH_MODE.AWS_IAM
});

リストクエリのフィルタリング

データが増加するにつれて、リストクエリをページネーションする必要があります。幸いなことに、これはAmplifyが生成したGraphQL APIに既に組み込まれています。

import { generateClient } from 'aws-amplify/api';
import { listTodos } from './graphql/queries';
const client = generateClient();
const variables = {
filter: {
priority: {
eq: 1
}
}
};
await client.graphql({
query: listTodos,
variables: variables
});
詳細
フィルタはどのように機能しますか?

GraphQLエクスプローラーのドキュメントペインまたは自動生成された/graphqlフォルダ内でスキーマを入力するのは次のようなものです:

listTodos(
filter: ModelTodoFilterInput
limit: Int
nextToken: String): ModelTodoConnection
input ModelTodoFilterInput {
id: ModelIDInput
priority: ModelIntInput
# ... all your other Todo fields here
and: [ModelTodoFilterInput]
or: [ModelTodoFilterInput]
not: ModelTodoFilterInput
}

スキーマの入力タイプは、それらに対して実行できるフィルタリングの種類を示します。例えば、ModelIntInputなどの整数フィールドには次のスキーマがあります:

input ModelIntInput {
ne: Int # "not equal to"
eq: Int # "equal to"
le: Int # "less than or equal to"
lt: Int # "less than"
ge: Int # "greater than or equal to"
gt: Int # "greater than"
between: [Int]
attributeExists: Boolean
attributeType: ModelAttributeTypes
}

これらのフィルタはフィールドのタイプに基づいて異なりますが、対応するAmazon DynamoDBクエリにリンクされています。

複合フィルタ

andornotブール論理でフィルタを組み合わせることができます。前の自動生成されたスキーマで観察すると、ModelTodoFilterInputはそれらのフィールドに関して再帰的です。したがって、例えば、priority値が1_または_2をフィルタリングしたい場合、次のようにします:

import { generateClient } from 'aws-amplify/api';
import { listTodos } from './graphql/queries';
const client = generateClient();
const variables = {
filter: {
or: [{ priority: { eq: 1 } }, { priority: { eq: 2 } }]
}
};
await client.graphql({
query: listTodos,
variables: variables
});

自然言語ではなくブール論理であるため、priorityが1と2の両方をクエリするとは何の結果も返されないことに注意してください。

リストクエリのページネーション

リストクエリ結果をページネーションするには、nextTokenlimit入力変数を設定して、後続のリストクエリリクエストを作成します。limit変数は、返される結果の数を制限します。応答には、次のページのデータをリクエストするために使用できるnextTokenが含まれます。nextTokenは、これらのフィルタで作成された次のクエリの開始アイテムのカーソルを表す非常に長い文字列です。

import { generateClient } from 'aws-amplify/api';
import { listTodos } from './graphql/queries';
const client = generateClient();
const res = await client.graphql({
query: listTodos,
variables: {
// Fetch first 20 records
limit: 20
}
});
const { items: itemsPage1, nextToken } = res.data.listTodos;
// Fetch the next 20 records
variables.nextToken = nextToken;
const res = await client.graphql({
query: listTodos,
variables: {
limit: 20
}
});
const { items: itemsPage2 } = res.data.listTodos;
ウォークスルー
GraphQL APIでページネーションを実装する

このウォークスルーは、ページネーションの実装に関する追加のステップバイステップのガイダンスを提供します。

大規模なレコードセットを使用する場合、最初のN個のアイテムのみを取得したい場合があります。例えば、Todoアプリの基本的なGraphQLスキーマから始めましょう:

type Todo @model {
id: ID!
title: String!
description: String
}

APIが@modelディレクティブで作成されると、以下のクエリが自動的に作成されます:

type Query {
getTodo(id: ID!): Todo
listTodos(
filter: ModelTodoFilterInput
limit: Int
nextToken: String
): ModelTodoConnection
}

次に、ModelTodoConnectionタイプを見て、listTodosクエリが実行されるときに返されるデータのアイデアを取得します:

type ModelTodoConnection {
items: [Todo]
nextToken: String
}

listTodosクエリを使用してAPIをクエリする場合、戻り値の型はModelTodoConnectionになります。これは、Todosの配列とnextTokenの両方を返すことができることを意味します。

nextTokenはページネーションを処理します。nextTokennullの場合、APIから返されるデータはこれ以上ありません。nextTokenが存在する場合、値を次のlistTodosクエリの引数として使用して、APIから次の選択セットを返すことができます。

これをテストするために、次のようなミューテーションを使用して5つのTodosを作成してください:

mutation createTodo {
createTodo(input: {
title: "Todo 1"
description: "My first todo"
}) {
id
title
description
}
}

次に、limit引数を指定してクエリ内のTodosの数の上限を設定できます。このクエリでは、上限を2つのアイテムに設定し、戻り値としてnextTokenをリクエストします:

query listTodos {
listTodos(limit: 2) {
items {
id
title
description
}
nextToken
}
}

次に、APIから次の2つのアイテムをクエリするには、このnextTokenを引数として指定します:

query listTodos {
listTodos(limit: 2, nextToken: <your_token>) {
items {
id
title
description
}
nextToken
}
}

返すべき他のアイテムがなくなると、応答のnextTokenはnullに設定されます。

JavaScriptアプリケーションからのクエリ

listTodosクエリはCLIによって自動生成されます。参照として、次のようなものになります:

const listTodos = `
query listTodos($limit: Int) {
listTodos(limit: $limit) {
items {
id
title
description
}
nextToken
}
}
`;

JavaScriptアプリケーションからのクエリにlimitを指定するには、以下のコードを使用して変数として上限を設定することができます:

import { generateClient } from 'aws-amplify/api';
const client = generateClient();
async function fetchTodos() {
const todoData = await client.graphql({
query: listTodos,
variables: {
limit: 2
}
});
console.log({ todoData });
}

APIリクエストから返されるデータは次のようなもので、items配列には作成されたアイテムがいくつか含まれます:

{
"data" {
"listTodos" {
"items": [{ id: "001", title: "Todo 1", description: "My first todo" }],
"nextToken": "<token-id>"
}
}
}

JavaScriptアプリケーションからのクエリにnextTokenを設定するには、以下のコードを使用できます:

import { generateClient } from 'aws-amplify/api';
const client = generateClient();
async function fetchTodos() {
const todoData = await client.graphql({
query: listTodos,
variables: {
limit: 2,
nextToken: '<token-id>'
}
});
console.log({ todoData });
}

制限事項:

  • 現在のところ、合計ページ数を取得するためのAPIはありません。すべてのアイテムをスキャンすることは潜在的に高コストな操作であることに注意してください。
  • ソートはDataStoreで利用可能ですが、AWS AppSyncでは利用できません。
  • AWS AppSyncスキーマはRelayの仕様のエッジ/ノードに従いませんが、精神的には似ています。
  • page番号でクエリすることはできません。nextTokenでクエリする必要があります。

読み取りリクエストをキャンセル

APIカテゴリを通じて作成されたクエリまたはミューテーションリクエストをキャンセルするには、返されたプロミスへの参照を保持することで可能です。

import { generateClient } from 'aws-amplify/api'
const client = generateClient()
const promise = client.graphql({ query: "..." });
try {
await promise;
} catch (error) {
console.log(error);
// If the error is because the request was cancelled you can confirm here.
if (client.isCancelError(error)) {
console.log(error.message); // "my message for cancellation"
// handle user cancellation logic
}
}
...
// To cancel the above request
client.cancel(promise, "my message for cancellation");

client.graphql()から返されたプロミスが変更されていないことを確認する必要があります。通常、async関数は返されるプロミスを別のプロミスでラップします。例えば、以下は機能しません:

import { generateClient } from 'aws-amplify/api';
const client = generateClient();
async function makeAPICall() {
return client.graphql({ query: '...' });
}
const promise = makeAPICall();
// The following will NOT cancel the request.
client.cancel(promise, 'my error message');

まとめ

おめでとうございます!アプリケーションデータの読み取りガイドを完了しました。このガイドでは、getおよびlistクエリを通じてデータを読み取る方法を学びました。

次のステップ

推奨される次のステップには、データのミューテーションを監視するためのリアルタイムイベントへのサブスクリプション、およびデータの情報アーキテクチャの構築と カスタマイズの続行が含まれます。このワークに役立つリソースには以下が含まれます: