AWS AppSync での Amazon OpenSearch Service リゾルバーの使用 - AWS AppSync GraphQL

AWS AppSync での Amazon OpenSearch Service リゾルバーの使用

注記

現在、主に APPSYNC_JS ランタイムとそのドキュメントをサポートしています。こちらにある APPSYNC_JS ランタイムとそのガイドの使用をご検討ください。

AWS AppSync は、AWS アカウントでプロビジョニングしたドメインからの Amazon OpenSearch Service の使用をサポートします (ドメインが VPC 内に存在しない場合)。ドメインをプロビジョニングした後、データソースを使用してそれに接続できます。この時点で、スキーマにリゾルバーを設定し、クエリ、ミューテーション、サブスクリプションなどの GraphQL 処理を実行することができます。このチュートリアルでは、いくつかの一般的な例を説明します。

詳細については、「OpenSearch 用リゾルバーのマッピングテンプレートリファレンス」を参照してください。

ワンクリックでのセットアップ

設定済みの Amazon OpenSearch Service を使用して AWS AppSync に GraphQL エンドポイントを自動的にセットアップするには、次の AWS CloudFormation テンプレートを使用します。

Blue button labeled "Launch Stack" with an arrow icon indicating an action to start.

AWS CloudFormation のデプロイが完了したら、GraphQL クエリとミューテーションの実行をすぐに開始できます。

OpenSearch Service ドメインを作成する

このチュートリアルを開始するには、既存の OpenSearch Service ドメインが必要です。ドメインがない場合は、次のサンプルが使用できます。OpenSearch Service ドメインの作成には最大 15 分かかることがあります。その後、AWS AppSync データソースと統合することができます。

aws cloudformation create-stack --stack-name AppSyncOpenSearch \ --template-url https://s3.us-west-2.amazonaws.com/awsappsync/resources/elasticsearch/ESResolverCFTemplate.yaml \ --parameters ParameterKey=OSDomainName,ParameterValue=ddtestdomain ParameterKey=Tier,ParameterValue=development \ --capabilities CAPABILITY_NAMED_IAM

AWS アカウントでは、米国西部 2 (オレゴン) 地区のこの AWS CloudFormationスタックを起動できます。

Blue button labeled "Launch Stack" with an arrow icon indicating an action to start.

OpenSearch Service のデータソースの設定

OpenSearch Service ドメインが作成されたら、AWS AppSync GraphQL API に移動し、[データソース] タブを選択します。[New (新規)] を選択して、データソースに「oss」などの分かりやすい名前を入力します。次に、[データソースタイプ][Amazon Opensearch ドメイン] を選択し、適切なリージョンを選択します。OpenSearch Service ドメインがリストに表示されます。このドメインを選択後、新規のロールを作成して、適切なアクセス許可を AWS AppSync に割り当てさせるか、次のようなインラインポリシーを含む既存のロールを選択します。

JSON
{ "Version":"2012-10-17", "Statement": [ { "Sid": "Stmt1234234", "Effect": "Allow", "Action": [ "es:ESHttpDelete", "es:ESHttpHead", "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut" ], "Resource": [ "arn:aws:es:us-east-1:111122223333:domain/democluster/*" ] } ] }

そのロールにはさらに、AWS AppSync との信頼関係を設定する必要があります。

JSON
{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "appsync.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }

さらに、OpenSearch Service ドメインには独自のアクセスポリシーがあります。これは Amazon OpenSearch Service コンソールを使用して変更できます。OpenSearch Service ドメインの適切なアクションとリソースを用いて、以下のように同じようなポリシーを追加する必要があります。Principal は AppSync のデータソースのロールです。これをコンソールに作成させる場合には、IAM コンソールに表示されるようにします。

JSON
{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/service-role/APPSYNC_DATASOURCE_ROLE" }, "Action": [ "es:ESHttpDelete", "es:ESHttpHead", "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut" ], "Resource": "arn:aws:es:us-east-1:111122223333:domain/DOMAIN_NAME/*" } ] }

リゾルバーを接続する

これで、データソースが OpenSearch Service ドメインに接続されたので、リゾルバーを使用して、以下の例のようにデータソースを GraphQL スキーマに接続することができます。

schema { query: Query mutation: Mutation } type Query { getPost(id: ID!): Post allPosts: [Post] } type Mutation { addPost(id: ID!, author: String, title: String, url: String, ups: Int, downs: Int, content: String): AWSJSON } type Post { id: ID! author: String title: String url: String ups: Int downs: Int content: String } ...

Post フィールドを含むユーザー定義の id 型があることに注意してください。次の例では、この型を OpenSearch Service ドメインに配置するプロセス (自動化可能) があることを前提としています。このプロセスでは、/post/_doc へのルートパスをマッピングします。post はインデックスです。このルートパスから、個々のドキュメントの検索、/id/post* によるワイルドカード検索、/post/_search の パスを使用した複数ドキュメントの検索が行えます。例えば、同じインデックス user でインデックスが付けられた User という別の型がある場合は、/user/_searchパスを使用して複数ドキュメントが検索できます。

AWS AppSync コンソールのスキーマエディタで前述の Postsスキーマを変更し、次のように searchPosts クエリを追加します。

type Query { getPost(id: ID!): Post allPosts: [Post] searchPosts: [Post] }

スキーマを保存します。右側の [searchPosts] で、[Attach resolver (リゾルバーをアタッチ)] を選択します。[アクション] メニューで [ランタイムの更新] を選択し、[ユニットリゾルバー (VTL のみ)] を選択します。次に、OpenSearch Service サービスのデータソースを選択します。[request mapping template (リクエストマッピングテンプレート)] セクションで、ドロップダウンから [Query posts (投稿のクエリ)] を選択し、基本テンプレートを取得します。path/post/_search に変更します。次のようになります。

{ "version":"2017-02-28", "operation":"GET", "path":"/post/_search", "params":{ "headers":{}, "queryString":{}, "body":{ "from":0, "size":50 } } }

これは、前述のスキーマの post フィールドの下に OpenSearch Service でインデックス化されたドキュメントがあることを前提としています。データ構造が異なる場合は、更新が必要です。

OpenSearch Service クエリからデータの結果を受信し、変換して GraphQL に渡す場合には、[レスポンスマッピングテンプレート] セクションで適切な _source フィルタを指定する必要があります。以下のテンプレートを使用してください。

[ #foreach($entry in $context.result.hits.hits) #if( $velocityCount > 1 ) , #end $utils.toJson($entry.get("_source")) #end ]

検索を変更する

前述のリクエストマッピングテンプレートは、すべてのレコードに簡単なクエリを実行します。今、特定の筆者で検索する場合を考えます。また、その筆者を、GraphQL クエリに定義した引数にするとします。AWS AppSync コンソールのスキーマエディタで、allPostsByAuthor クエリを次のように追加します。

type Query { getPost(id: ID!): Post allPosts: [Post] allPostsByAuthor(author: String!): [Post] searchPosts: [Post] }

その後、[リゾルバーをアタッチ] を選択し、OpenSearch Service データソースを選択します。ただし、[レスポンスマッピングテンプレート] には次の例を使用します。

{ "version":"2017-02-28", "operation":"GET", "path":"/post/_search", "params":{ "headers":{}, "queryString":{}, "body":{ "from":0, "size":50, "query":{ "match" :{ "author": $util.toJson($context.arguments.author) } } } } }

body には author フィールドを含む term クエリが含まれていることに注意してください。これは引数としてクライアントから渡されます。任意で、標準テキストなどの事前に入力された情報を追加したり、他のユーティリティを使用したりすることもできます。

このリゾルバーを使用している場合、以前の例と同じ情報をレスポンスマッピングテンプレートに入力します。

OpenSearch Service へのデータの追加

GraphQL ミューテーションの結果、OpenSearch Service ドメインにデータの追加が必要になる場合があります。これは検索やその他の目的に非常に役立ちます。GraphQL サブスクリプションを使用してデータをリアルタイムで作成できるため、これは OpenSearch Service ドメインのデータの更新をクライアントに通知するメカニズムとして動作します。

AWS AppSync コンソールで [スキーマ] ページに戻り、addPost() ミューテーションで [Attach resolver (リゾルバーをアタッチ)] を選択します。再度 OpenSearch Service データソースを選択し、Posts スキーマに次のレスポンスマッピングテンプレートを使用します。

{ "version":"2017-02-28", "operation":"PUT", "path": $util.toJson("/post/_doc/$context.arguments.id"), "params":{ "headers":{}, "queryString":{}, "body":{ "id": $util.toJson($context.arguments.id), "author": $util.toJson($context.arguments.author), "ups": $util.toJson($context.arguments.ups), "downs": $util.toJson($context.arguments.downs), "url": $util.toJson($context.arguments.url), "content": $util.toJson($context.arguments.content), "title": $util.toJson($context.arguments.title) } } }

以前と同様、これはデータ構造の一例です。別のフィールド名またはインデックスがある場合は、必要に応じて pathbody を更新します。この例では、GraphQL ミューテーションの引数からテンプレートを受け取るために $context.arguments を使用する方法も示されています。

次に進む前に、以下のレスポンスマッピングテンプレートを使用してください。これにより、ミューテーション操作の結果またはエラー情報が出力として返されます。

#if($context.error) $util.toJson($ctx.error) #else $util.toJson($context.result) #end

単一のドキュメントの取得

最後に、スキーマで getPost(id:ID) クエリを使用して個別にドキュメントを受け取る場合には、AWS AppSync コンソールのスキーマエディタでこのクエリを探し、[Attach resolver (リゾルバーをアタッチ)] を選択します。再度 OpenSearch Service データソースを選択し、次のマッピングテンプレートを使用します。

{ "version":"2017-02-28", "operation":"GET", "path": $util.toJson("post/_doc/$context.arguments.id"), "params":{ "headers":{}, "queryString":{}, "body":{} } }

上記の path では id 引数の body が空であるため、単一のドキュメントが返ります。ただし、リストではなく単一の項目が返るため、次のレスポンスマッピングテンプレートを使用する必要があります。

$utils.toJson($context.result.get("_source"))

クエリとミューテーションを実行する

これで、OpenSearch Service ドメインに対して GraphQL 処理が実行できます。AWS AppSync コンソールの [クエリ] タブに移動し、次のように新しいレコードを追加します。

mutation addPost { addPost ( id:"12345" author: "Fred" title: "My first book" content: "This will be fun to write!" url: "publisher website", ups: 100, downs:20 ) }

ミューテーションの結果が右側に表示されます。同様に、OpenSearch Service ドメインに対して searchPosts クエリが実行できます。

query searchPosts { searchPosts { id title author content } }

ベストプラクティス

  • OpenSearch Service はプライマリデータベースとしてではなく、データのクエリ発行のために使用します。「GraphQL リゾルバーを組み合わせる」で説明したように、Amazon DynamoDB と組み合わせて OpenSearch Service を使用する場合があります。

  • AWS AppSync サービスロールにクラスターへのアクセスを許可することにより、ドメインへのアクセスのみを許可します。

  • 開発中は、最小限のコストのクラスターを使用して小規模で開始し、その後、本稼働への移行時に高可用性 (HA) を備えた大規模なクラスターへと移行することができます。