

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 中結合 GraphQL 解析程式 AWS AppSync
<a name="tutorial-combining-graphql-resolvers-js"></a>

GraphQL 結構描述中的解析程式與欄位具有一對一的關係，以及高度的彈性。由於資料來源是在獨立於結構描述的解析程式上設定，因此您能夠透過不同的資料來源解析或操作 GraphQL 類型，讓您混合並比對結構描述，以最符合您的需求。

下列案例示範如何在結構描述中混合和比對資料來源。開始之前，您應該熟悉為 Amazon DynamoDB 和 Amazon OpenSearch Service AWS Lambda設定資料來源和解析程式。

## 範例結構描述
<a name="example-schema-js"></a>

下列結構描述的類型為 `Post`，每個都有三個 `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
}
```

在此範例中，您總共會有六個解析程式，每個解析程式都需要資料來源。解決此問題的一種方法是將這些關聯到稱為 的單一 Amazon DynamoDB 資料表`Posts`，其中 `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 用戶端 (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 的資料）。這在將進階搜尋操作新增至您的應用程式時非常強大，例如關鍵字、模糊字詞配對，甚至是地理空間查詢。可以透過 ETL 程序從 DynamoDB 傳輸資料，或者，您可以使用 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 中，因此您可以使用自由格式文字搜尋作者或內容欄位，即使是空格，如下所示：

```
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 資料表`id`，而 DynamoDB 來源的任何變更都會串流到您的 OpenSearch Service 網域。如需進行這項設定的詳細資訊，請參閱 [DynamoDB 串流文件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html)。