

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# での GraphQL リゾルバーの組み合わせ AWS AppSync
<a name="tutorial-combining-graphql-resolvers-js"></a>

GraphQL スキーマのリゾルバーとフィールドには、非常に柔軟性の高い 1 対 1 の関係があります。データソースはスキーマとは独立してリゾルバーに設定されるため、ニーズに応じてスキーマ上で組み合わせやマッチングを行い、さまざまなデータソースを使用して GraphQL 型の解決や操作が行うことができます。

次のシナリオでは、スキーマ内のデータソースを組み合わせやマッチングを行う方法を紹介します。開始する前に、、Amazon DynamoDB AWS Lambda、Amazon OpenSearch Service のデータソースとリゾルバーの設定について理解しておく必要があります。

## スキーマの例
<a name="example-schema-js"></a>

次のスキーマは `Post` タイプで、それぞれ 3 つの `Query` と `Mutation` オペレーションがあります。

```
type Post {
    id: ID!
    author: String!
    title: String
    content: String
    url: String
    ups: Int
    downs: Int
    version: Int!
}

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

type Mutation {
    addPost(
        id: ID!,
        author: String!,
        title: String,
        content: String,
        url: String
    ): Post
    updatePost(
        id: ID!,
        author: String!,
        title: String,
        content: String,
        url: String,
        ups: Int!,
        downs: Int!,
        expectedVersion: Int!
    ): Post
    deletePost(id: ID!): Post
}
```

この例では、それぞれにデータソースが必要な、合計で 6 つのリゾルバーを使用します。この問題を解決する 1 つの方法は、`Posts` と呼ばれる 1 つの Amazon DynamoDB テーブルにこれらをフックすることです。このテーブルでは、`AllPost` フィールドがスキャンを実行し、`searchPosts` フィールドがクエリを実行します (「[DynamoDB 用の JavaScript リゾルバー関数リファレンス](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html)」を参照)。ただし、Amazon DynamoDB に限ったことではありません。Lambda や OpenSearch Service など、ビジネス要件を満たすために存在してします。

## リゾルバーを使用してデータを変更する
<a name="alter-data-through-resolvers-js"></a>

 AWS AppSync データソースによって直接サポートされていないサードパーティーデータベースから結果を返す必要がある場合があります。また、データを API クライアントに返す前に、データに複雑な変更を加える必要がある場合もあります。これは、クライアントでのタイムスタンプの相違や、後方互換性の問題の処理など、データ型の不適切なフォーマットが原因の可能性があります。この場合、 AWS Lambda 関数をデータソースとして AWS AppSync API に接続するのが適切なソリューションです。説明のために、次の例では、 AWS Lambda 関数はサードパーティーのデータストアから取得されたデータを操作します。

```
export const handler = (event, context, callback) => {
    // fetch data
    const result = fetcher()

    // apply complex business logic
    const data = transform(result)	

    // return to AppSync
    return data
};
```

これは完全に有効な Lambda 関数であり、GraphQL スキーマの `AllPost` フィールドにアタッチできるため、すべての結果を返すクエリが、賛成/反対に対するランダムな番号を受け取ります。

## DynamoDB と OpenSearch Service
<a name="ddb-and-es-js"></a>

一部のアプリケーションでは、DynamoDB に対してミューテーションまたは簡単な検索クエリを実行し、バックグラウンドプロセスでドキュメントを OpenSearch Service に転送する場合があります。その後、`searchPosts` リゾルバーを OpenSearch Service データソースに単純にアタッチし、GraphQL クエリを使用して、(DynamoDB のデータからの) 検索結果を返します。これは、キーワードやあいまいワードによる検索、地理空間検索などの高度な検索処理をアプリケーションに追加する場合に非常に役立ちます。DynamoDB からのデータ転送は、ETL プロセスを使用して、または Lambda を使用した DynamoDB からのストリームを使用して行うことができます。

これらの特定のデータソースを使い始めるには、[DynamoDB](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-dynamodb-resolvers-js.html) と [Lambda](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-lambda-resolvers-js.html) のチュートリアルを参照してください。

例えば、前のチュートリアルのスキーマを使用すると、次のミューテーションによって DynamoDB に項目が追加されます。

```
mutation addPost {
  addPost(
    id: 123
    author: "Nadia"
    title: "Our first post!"
    content: "This is our first post."
    url: "https://aws.amazon.com/appsync/"
  ) {
    id
    author
    title
    content
    url
    ups
    downs
    version
  }
}
```

これにより、データが DynamoDB に書き込まれます。その後、Lambda を介してデータが Amazon OpenSearch Service に転送されます。ここではすべての投稿がさまざまなフィールドについて検索できます。例えば、データが Amazon OpenSearch Service にあるため、以下のようにスペースを含む任意のテキストを使用して、author フィールドまたは content フィールドを検索できます。

```
query searchName{
    searchAuthor(name:"   Nadia   "){
        id
        title
        content
    }
}

---------- or ----------

query searchContent{
    searchContent(text:"test"){
        id
        title
        content
    }
}
```

データは DynamoDB に直接書き込まれるため、`allPost{...}` クエリと `getPost{...}` クエリを使用して、テーブルに対するリストまたは項目の検索処理が効率的に実行できます。このスタックでは、DynamoDB ストリームに対して次のコード例を使用します。

**注記**  
この Python コードは一例であり、本番稼働用コードでの使用を意図したものではありません。

```
import boto3
import requests
from requests_aws4auth import AWS4Auth

region = '' # e.g. us-east-1
service = 'es'
credentials = boto3.Session().get_credentials()
awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)

host = '' # the OpenSearch Service domain, e.g. https://search-mydomain.us-west-1.es.amazonaws.com
index = 'lambda-index'
datatype = '_doc'
url = host + '/' + index + '/' + datatype + '/'

headers = { "Content-Type": "application/json" }

def handler(event, context):
    count = 0
    for record in event['Records']:
        # Get the primary key for use as the OpenSearch ID
        id = record['dynamodb']['Keys']['id']['S']

        if record['eventName'] == 'REMOVE':
            r = requests.delete(url + id, auth=awsauth)
        else:
            document = record['dynamodb']['NewImage']
            r = requests.put(url + id, auth=awsauth, json=document, headers=headers)
        count += 1
    return str(count) + ' records processed.'
```

DynamoDB ストリームを使用し、 をプライマリキーとしてこれを DynamoDB テーブルにアタッチできます。DynamoDB のソースへの変更は OpenSearch Service ドメインに転送されます。この設定の詳細については、[DynamoDB Streams のドキュメント](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html)を参照してください。