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

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

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

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

import { API } from 'aws-amplify';
import * as queries from './graphql/queries';
import { GraphQLQuery } from '@aws-amplify/api';
import { ListTodosQuery, GetTodoQuery } from './API';
// Simple query
const allTodos = await API.graphql<GraphQLQuery<ListTodosQuery>>({
query: queries.listTodos
});
console.log(allTodos); // result: { "data": { "listTodos": { "items": [/* ..... */] } } }
// Fetch a single record by its identifier
const oneTodo = await API.graphql<GraphQLQuery<GetTodoQuery>>({
query: queries.getTodo,
variables: { id: 'some id' }
});
import { API } from 'aws-amplify';
import * as queries from './graphql/queries';
// Simple query
const allTodos = await API.graphql({ query: queries.listTodos });
console.log(allTodos); // result: { "data": { "listTodos": { "items": [/* ..... */] } } }
//Fetch a single record by its identifier
const oneTodo = await API.graphql({
query: queries.getTodo,
variables: { id: 'some id' }
});
トラブルシューティング
権限がないエラーをトラブルシューティングする

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

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

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

前の例では、Todo の各サインインユーザー、つまり「所有者」は、自分の 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 キー認証を通じたパブリック読み取りと IAM 認証を通じた認証済み読み取りがある場合に便利です。次の例は、カスタム認可モードでデータをクエリする方法を示しています:

import { API } from 'aws-amplify';
import { GraphQLQuery, GRAPHQL_AUTH_MODE } from '@aws-amplify/api';
import * as queries from './graphql/queries';
import { GetTodoQuery } from './API';
const todos = await API.graphql<GraphQLQuery<GetTodoQuery>>({
query: queries.listTodos,
authMode: GRAPHQL_AUTH_MODE.AWS_IAM
});
import { API } from 'aws-amplify';
import { GRAPHQL_AUTH_MODE } from '@aws-amplify/api';
import * as queries from './graphql/queries';
const todos = await API.graphql({
query: queries.listTodos,
authMode: GRAPHQL_AUTH_MODE.AWS_IAM
});

リストクエリをフィルタリングする

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

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

入力スキーマは GraphQL エクスプローラーの Docs ペインまたは自動生成された /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
}

スキーマの入力タイプは、それらに対して実行できるフィルタリングの種類を示します。たとえば、priority などの整数フィールドは 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 クエリ にリンクされています。

複合フィルタ

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

import { API } from 'aws-amplify';
import { listTodos } from './graphql/queries';
import { ListTodosQueryVariables, ListTodosQuery } from './API';
const variables: ListTodosQueryVariables = {
filter: {
or: [{ priority: { eq: 1 } }, { priority: { eq: 2 } }]
}
};
await API.graphql<GraphQLQuery<ListTodosQuery>>({
query: listTodos,
variables: variables
});
import { API } from 'aws-amplify';
import { listTodos } from './graphql/queries';
const variables = {
filter: {
or: [{ priority: { eq: 1 } }, { priority: { eq: 2 } }]
}
};
await API.graphql({
query: listTodos,
variables: variables
});

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

リストクエリをページネーションする

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

import { API } from 'aws-amplify';
import { listTodos } from './graphql/queries';
import { ListTodosQueryVariables, ListTodosQuery } from './API';
// Fetch first 20 records
const variables: ListTodosQueryVariables = {
limit: 20
// add filter as needed
};
const res =
(await API.graphql) <
GraphQLQuery<ListTodosQuery>({
query: listTodos,
variables: variables
});
const { items: itemsPage1, nextToken } = res.data?.listTodos;
// Fetch the next 20 records
variables.nextToken = nextToken;
const res =
(await API.graphql) <
GraphQLQuery<ListTodosQuery>({
query: listTodos,
variables: variables
});
const { items: itemsPage2 } = res.data?.listTodos;
import { API } from 'aws-amplify';
import { listTodos } from './graphql/queries';
// Fetch first 20 records
const variables = {
limit: 20
// add filter as needed
};
const res = await API.graphql({
query: listTodos,
variables: variables
});
const { items: itemsPage1, nextToken } = res.data.listTodos;
// Fetch the next 20 records
variables.nextToken = nextToken;
const res = await API.graphql({
query: listTodos,
variables: variables
});
const { items: itemsPage2 } = res.data.listTodos;
チュートリアル
GraphQL API でページネーションを実装する

このショートチュートリアルでは、ページネーション実装の追加のステップバイステップガイダンスを提供します。

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

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

@model ディレクティブを使用して API が作成される場合、以下のクエリが自動的に作成されます:

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 つの Todo を作成してみてください:

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

次に、limit 引数を指定することでクエリ内の Todo の数の制限を設定できます。このクエリでは、制限を 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 { API } from 'aws-amplify';
async function fetchTodos() {
const todoData = await API.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 { API } from 'aws-amplify';
async function fetchTodos() {
const todoData = await API.graphql({
query: listTodos,
variables: {
limit: 2,
nextToken: '<token-id>'
}
});
console.log({ todoData });
}

制限事項:

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

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

API カテゴリー経由で行われたクエリまたはミューテーションリクエストをキャンセルするには、返されるプロミスへの参照を保持します。

const promise = API.graphql({ query: "..." });
try {
await promise;
} catch (error) {
console.log(error);
// If the error is because the request was cancelled you can confirm here.
if (API.isCancel(error)) {
console.log(error.message); // "my message for cancellation"
// handle user cancellation logic
}
}
...
// To cancel the above request
API.cancel(promise, "my message for cancellation");

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

async function makeAPICall() {
return API.graphql({ query: '...' });
}
const promise = makeAPICall();
// The following will NOT cancel the request.
API.cancel(promise, 'my error message');

まとめ

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

次のステップ

推奨される次のステップには、リアルタイムイベントをサブスクライブしてデータの変異を確認し、情報アーキテクチャを継続的に構築およびカスタマイズすることが含まれます。このワークに役立つリソースは以下のとおりです: