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

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

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

詳細については、「OpenSearch 用の JavaScript リゾルバー関数リファレンス」を参照してください。

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

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

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

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

リゾルバーを接続する

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

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 を見つけ、「アタッチ」を選択します OpenSearch Service のデータソースを選択し、リゾルバーを保存します。以下のスニペットを使用してリゾルバーのコードを更新してください。

import { util } from '@aws-appsync/utils' /** * Searches for documents by using an input term * @param {import('@aws-appsync/utils').Context} ctx the context * @returns {*} the request */ export function request(ctx) { return { operation: 'GET', path: `/post/_search`, params: { body: { from: 0, size: 50 } }, } } /** * Returns the fetched items * @param {import('@aws-appsync/utils').Context} ctx the context * @returns {*} the result */ export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type) } return ctx.result.hits.hits.map((hit) => hit._source) }

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

検索を変更する

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

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

リゾルバー」ペインで allPostsByAuthor を見つけて「アタッチ」を選択します。OpenSearch Service のデータソースを選択し、以下のコードを使用してください。

import { util } from '@aws-appsync/utils' /** * Searches for documents by `author` * @param {import('@aws-appsync/utils').Context} ctx the context * @returns {*} the request */ export function request(ctx) { return { operation: 'GET', path: '/post/_search', params: { body: { from: 0, size: 50, query: { match: { author: ctx.args.author } }, }, }, } } /** * Returns the fetched items * @param {import('@aws-appsync/utils').Context} ctx the context * @returns {*} the result */ export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type) } return ctx.result.hits.hits.map((hit) => hit._source) }

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

OpenSearch Service へのデータの追加

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

AWS AppSync コンソールで [スキーマ] ページに戻り、addPost() ミューテーションで [アタッチ] を選択します。OpenSearch Service のデータソースをもう一度選択し、以下のコードを使用してください。

import { util } from '@aws-appsync/utils' /** * Searches for documents by `author` * @param {import('@aws-appsync/utils').Context} ctx the context * @returns {*} the request */ export function request(ctx) { return { operation: 'PUT', path: `/post/_doc/${ctx.args.id}`, params: { body: ctx.args }, } } /** * Returns the inserted post * @param {import('@aws-appsync/utils').Context} ctx the context * @returns {*} the result */ export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type) } return ctx.result }

以前と同様、これはデータ構造の一例です。別のフィールド名またはインデックスがある場合は、必要に応じて pathbody を更新します。この例では context.arguments の使用方法も示しています。リクエストハンドラーはctx.argsと記述することもできます。

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

最後に、スキーマで getPost(id:ID) クエリを使用して個別にドキュメントを受け取る場合には、AWS AppSync コンソールのスキーマエディタでこのクエリを探し、[アタッチ] を選択します。OpenSearch Service のデータソースをもう一度選択し、以下のコードを使用してください。

import { util } from '@aws-appsync/utils' /** * Searches for documents by `author` * @param {import('@aws-appsync/utils').Context} ctx the context * @returns {*} the request */ export function request(ctx) { return { operation: 'GET', path: `/post/_doc/${ctx.args.id}`, } } /** * Returns the post * @param {import('@aws-appsync/utils').Context} ctx the context * @returns {*} the result */ export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type) } return ctx.result._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 search { searchPosts { id title author content } }

ベストプラクティス

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

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

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