

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

# AWS AppSync 解析程式參考 (JavaScript)
<a name="resolver-reference-js-version"></a>

下列各節包含`APPSYNC_JS`執行期和 JavaScript 解析程式參考：
+  [ JavaScript 解析程式概觀 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html) - 進一步了解解析程式的運作方式 AWS AppSync。
+  [ 解析程式內容物件參考 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) - 進一步了解內容物件及其在解析程式中的使用方式。
+  [ 解析程式和函數的 JavaScript 執行期功能 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html) - 進一步了解支援的執行期功能，以及使用公用程式簡化程式碼。
+  [ DynamoDB 的 JavaScript 解析程式函數參考 ](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html) - 進一步了解解析程式如何與 DynamoDB 互動。
+  [ OpenSearch 的 JavaScript 解析程式函數參考 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-elasticsearch-js.html) - 進一步了解解析程式請求和回應結構，以及與 OpenSearch Service 的互動。
+  [ Lambda 的 JavaScript 解析程式函數參考 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-lambda-js.html) - 進一步了解解析程式請求和回應結構，以及與 Lambda 的互動。
+  [ EventBridge 資料來源的 JavaScript 解析程式函數參考 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-eventbridge-js.html) - 進一步了解解析程式請求和回應結構，以及與 EventBridge 的互動。
+  [ 無資料來源的 JavaScript 解析程式函數參考 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-none-js.html) - 進一步了解解析程式請求和回應結構，以及與 NONE 資料來源的互動。
+  [ HTTP 的 JavaScript 解析程式函數參考 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-http-js.html) - 進一步了解解析程式請求和回應結構，以及與 HTTP 端點的互動。
+  [ Amazon RDS 的 JavaScript 解析程式函數參考 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-rds-js.html) - 進一步了解解析程式結構和與 RDS 的互動。
+  [ Amazon Bedrock 的 JavaScript 解析程式函數參考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html) - 進一步了解解析程式結構和與 Amazon Bedrock 的互動。

# AWS AppSync JavaScript 解析程式概觀
<a name="resolver-reference-overview-js"></a>

AWS AppSync 可讓您透過對資料來源執行操作來回應 GraphQL 請求。對於您想要執行查詢、變動或訂閱的每個 GraphQL 欄位，必須連接解析程式。

解析程式是 GraphQL 和資料來源之間的連接器。他們 tell AWS AppSync 如何將傳入的 GraphQL 請求轉譯為後端資料來源的指示，以及如何將來自該資料來源的回應轉譯回 GraphQL 回應。透過 AWS AppSync，您可以使用 JavaScript 撰寫解析程式，並在 AWS AppSync (`APPSYNC_JS`) 環境中執行。

AWS AppSync 可讓您撰寫由管道中多個 AWS AppSync 函數組成的單位解析程式或管道解析程式。

## 支援的執行時間功能
<a name="runtime-support-js"></a>

 AWS AppSync JavaScript 執行時間提供 JavaScript 程式庫、公用程式和功能的子集。如需`APPSYNC_JS`執行時間支援的完整功能清單，請參閱[解析程式和函數的 JavaScript 執行時間功能](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)。

## 單位解析程式
<a name="unit-resolver-js"></a>

單位解析程式由程式碼組成，可定義針對資料來源執行的請求和回應處理常式。請求處理常式會將內容物件做為引數，並傳回用來呼叫資料來源的請求承載。回應處理常式會從資料來源接收承載，其中包含執行請求的結果。回應處理常式會將承載轉換為 GraphQL 回應，以解析 GraphQL 欄位。在下列範例中，解析程式會從 DynamoDB 資料來源擷取項目：

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
  return ddb.get({ key: { id: ctx.args.id } });
}

export const response = (ctx) => ctx.result;
```

## JavaScript 管道解析程式的剖析
<a name="anatomy-of-a-pipeline-resolver-js"></a>

管道解析程式由程式碼組成，可定義請求和回應處理常式，以及函數清單。每個函數都有一個針對資料來源執行的**請求**和**回應**處理常式。由於管道解析程式委派會執行到函數清單，因此不會連結到任何資料來源。單位解析程式和函數是對資料來源執行操作的基本元素。

### 管道解析程式請求處理常式
<a name="request-handler-js"></a>

管道解析程式的請求處理常式 （步驟前） 可讓您在執行定義的函數之前執行一些準備邏輯。

### 函數清單
<a name="functions-list-js"></a>

管道解析程式將會依序執行的函數清單。管道解析程式請求處理常式評估結果會以 的形式提供給第一個函數`ctx.prev.result`。每個函數評估結果都以 的形式提供給下一個函數`ctx.prev.result`。

### 管道解析程式回應處理常式
<a name="response-handler-js"></a>

管道解析程式的回應處理常式可讓您執行從最後一個函數輸出到預期 GraphQL 欄位類型的一些最終邏輯。函數清單中最後一個函數的輸出可在管道解析程式回應處理常式中作為 `ctx.prev.result`或 使用`ctx.result`。

### 執行流程
<a name="execution-flow-js"></a>

假設管道解析程式包含兩個函數，以下清單代表呼叫解析程式時的執行流程：

1.  管道解析程式請求處理常式

1.  函數 1：函數請求處理常式 

1.  第 1 個函數：資料來源呼叫 

1.  函數 1：函數回應處理常式 

1.  函數 2：函數請求處理常式 

1.  第 2 個函數：資料來源呼叫 

1.  函數 2：函數回應處理常式 

1.  管道解析程式回應處理常式 

![\[GraphQL request flow diagram showing interactions between request, data sources, and response components.\]](http://docs.aws.amazon.com/zh_tw/appsync/latest/devguide/images/appsync-js-resolver-logic.png)


### 實用的`APPSYNC_JS`執行期內建公用程式
<a name="useful-utilities-js"></a>

下列公用程式可在您使用管道解析程式時提供協助。

#### ctx.stash
<a name="ctx-stash-js"></a>

停滯是在每個解析程式和函數請求和回應處理常式中可用的物件。相同的 stash 執行個體透過單一解析程式執行運作。這表示您可以使用 stash 跨請求和回應處理常式，以及管道解析程式中的函數傳遞任意資料。您可以像一般 JavaScript 物件一樣測試堆疊。

#### ctx.prev.result
<a name="ctx-prev-result-js"></a>

`ctx.prev.result` 會顯示管道先前執行操作的結果。如果先前的操作是管道解析程式請求處理常式，則 `ctx.prev.result` 可供鏈結中的第一個函數使用。如果先前操作是第一個函數，則 `ctx.prev.result` 會顯示第一個函數的輸出，並將資料提供給管道中的第二個函數。如果先前的操作是最後一個函數，則 `ctx.prev.result` 代表最後一個函數的輸出，並可供管道解析程式回應處理常式使用。

#### util.error
<a name="util-error-js"></a>

`util.error` 公用程式非常適合用來擲出欄位錯誤。在函數請求或回應處理常式`util.error`內使用 會立即擲回欄位錯誤，以防止後續函數執行。如需詳細資訊和其他`util.error`簽章，請造訪[解析程式和函數的 JavaScript 執行期功能](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)。

#### util.appendError
<a name="util-appenderror-js"></a>

`util.appendError` 類似於 `util.error()`，主要區別在於它不會中斷處理常式的評估。相反地，它表示 欄位發生錯誤，但允許評估處理常式並因此傳回資料。在函數中使用 `util.appendError` 並不會中斷管道的執行流程。如需詳細資訊和其他`util.error`簽章，請造訪[解析程式和函數的 JavaScript 執行期功能](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)。

#### runtime.earlyReturn
<a name="runtime-earlyreturn-js"></a>

`runtime.earlyReturn` 函數可讓您從任何請求函數提早傳回 。在解析程式請求處理常式`runtime.earlyReturn`內部使用 會從解析程式傳回 。從函數 AWS AppSync 請求處理常式呼叫它會從函數傳回，並繼續執行到管道中的下一個函數或解析程式回應處理常式。

### 撰寫管道解析程式
<a name="writing-resolvers"></a>

管道解析程式也有一個請求和一個回應處理常式，圍繞管道中函數的執行：其請求處理常式在第一個函數的請求之前執行，而其回應處理常式在最後一個函數的回應之後執行。解析程式請求處理常式可以設定要供管道中的函數使用的資料。解析程式回應處理常式負責傳回映射至 GraphQL 欄位輸出類型的資料。在下列範例中，解析程式請求處理常式會定義 `allowedGroups`；傳回的資料應屬於其中一個群組。此值可供解析程式的 函數用來請求資料。解析程式的回應處理常式會執行最終檢查並篩選結果，以確保只會傳回屬於允許群組的項目。

```
import { util } from '@aws-appsync/utils';

/**
 * Called before the request function of the first AppSync function in the pipeline.
 *  @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
  ctx.stash.allowedGroups = ['admin'];
  ctx.stash.startedAt = util.time.nowISO8601();
  return {};
}
/**
 * Called after the response function of the last AppSync function in the pipeline.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  const result = [];
  for (const item of ctx.prev.result) {
    if (ctx.stash.allowedGroups.indexOf(item.group) > -1) result.push(item);
  }
  return result;
}
```

#### 撰寫 AWS AppSync 函數
<a name="writing-functions"></a>

AWS AppSync 函數可讓您撰寫常見邏輯，以便在結構描述中的多個解析程式之間重複使用。例如，您可以有一個稱為 `QUERY_ITEMS` 的 AWS AppSync 函數，負責從 Amazon DynamoDB 資料來源查詢項目。對於您要查詢項目的解析程式，只需將 函數新增至解析程式的管道，並提供要使用的查詢索引。邏輯不需要重新實作。

## 補充主題
<a name="supplemental-topics"></a>

**主題**
+ [使用 Amazon DynamoDB 的範例管道解析程式](https://docs.aws.amazon.com/appsync/latest/devguide/writing-code.html)
+ [設定`APPSYNC_JS`執行時間的公用程式](https://docs.aws.amazon.com/appsync/latest/devguide/utility-resolvers.html)
+ [`APPSYNC_JS`執行時間的綁定、TypeScript 和來源映射](https://docs.aws.amazon.com/appsync/latest/devguide/additional-utilities.html)
+ [測試您的解析程式和函數處理常式](https://docs.aws.amazon.com/appsync/latest/devguide/test-resolvers.html)
+ [從 VTL 遷移到 JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/migrating-resolvers.html)
+ [在直接資料來源存取和透過 Lambda 資料來源代理之間進行選擇](https://docs.aws.amazon.com/appsync/latest/devguide/choosing-data-source.html)

# 使用 Amazon DynamoDB 的範例管道解析程式
<a name="writing-code"></a>

假設您想要在名為 的欄位上連接管道解析程式`getPost(id:ID!)`，該欄位會從具有下列 GraphQL 查詢的 Amazon DynamoDB 資料來源傳回`Post`類型：

```
getPost(id:1){
    id
    title
    content
}
```

首先，`Query.getPost`使用下面的程式碼將簡單的解析程式連接到 。這是簡單解析程式程式碼的範例。請求處理常式中未定義邏輯，回應處理常式只會傳回最後一個函數的結果。

```
/**
 * Invoked **before** the request handler of the first AppSync function in the pipeline.
 * The resolver `request` handler allows to perform some preparation logic
 * before executing the defined functions in your pipeline.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
  return {}
}

/**
 * Invoked **after** the response handler of the last AppSync function in the pipeline.
 * The resolver `response` handler allows to perform some final evaluation logic
 * from the output of the last function to the expected GraphQL field type.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  return ctx.prev.result
}
```

接著，定義從資料來源擷取後置項目`GET_ITEM`的函數：

```
import { util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'

/**
 * Request a single item from the attached DynamoDB table datasource
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
	const { id } = ctx.args
	return ddb.get({ key: { id } })
}

/**
 * Returns the result
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
	const { error, result } = ctx
	if (error) {
		return util.appendError(error.message, error.type, result)
	}
	return ctx.result
}
```

如果在請求期間發生錯誤，函數的回應處理常式會附加錯誤，並在 GraphQL 回應中傳回呼叫用戶端。將 `GET_ITEM`函數新增至解析程式函數清單。當您執行查詢時，`GET_ITEM`函數的請求處理常式會使用 AWS AppSync DynamoDB 模組提供的 utils，以使用 `id`做為金鑰來建立`DynamoDBGetItem`請求。 `ddb.get({ key: { id } })`會產生適當的`GetItem`操作：

```
{
    "operation" : "GetItem",
    "key" : {
        "id" : { "S" : "1" }
    }
}
```

AWS AppSync 使用 請求從 Amazon DynamoDB 擷取資料。一旦傳回資料，就會由`GET_ITEM`函數的回應處理常式處理，它會檢查錯誤，然後傳回結果。

```
{
  "result" : {
    "id": 1,
    "title": "hello world",
    "content": "<long story>"
  }
}
```

最後，解析程式的回應處理常式會直接傳回結果。

## 使用錯誤
<a name="working-with-errors"></a>

如果在請求期間函數中發生錯誤，則會在 中的函數回應處理常式中提供該錯誤`ctx.error`。您可以使用 `util.appendError`公用程式將錯誤附加至 GraphQL 回應。您可以使用 stash，將錯誤提供給管道中的其他 函數。請參閱以下範例：

```
/**
 * Returns the result
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  const { error, result } = ctx;
  if (error) {
    if (!ctx.stash.errors) ctx.stash.errors = []
    ctx.stash.errors.push(ctx.error)
    return util.appendError(error.message, error.type, result);
  }
  return ctx.result;
}
```

# 設定`APPSYNC_JS`執行時間的公用程式
<a name="utility-resolvers"></a>

AWS AppSync 提供兩個程式庫，協助開發具有`APPSYNC_JS`執行時間的解析程式：
+ `@aws-appsync/eslint-plugin` - 在開發期間快速攔截和修正問題。
+ `@aws-appsync/utils` - 在程式碼編輯器中提供類型驗證和自動完成。

## 設定 eslint 外掛程式
<a name="utility-resolvers-configuring-eslint-plugin"></a>

[ESLint](https://eslint.org/) 是一種工具，可靜態分析程式碼以快速找出問題。您可以執行 ESLint 做為持續整合管道的一部分。 `@aws-appsync/eslint-plugin` 是一種 ESLint 外掛程式，在利用`APPSYNC_JS`執行時間時，可在程式碼中擷取無效的語法。外掛程式可讓您在開發期間快速取得程式碼的意見回饋，而不必將變更推送至雲端。

`@aws-appsync/eslint-plugin` 提供兩個規則集，您可以在開發期間使用。

**「plugin：@aws-appsync/base」**會設定一組基本規則，供您在專案中運用：


| 規則 | Description | 
| --- | --- | 
| 無非同步 | 不支援非同步程序和承諾。 | 
| 無等待 | 不支援非同步程序和承諾。 | 
| 無類別 | 不支援類別。 | 
| 無 | for 不支援 (for-of受支援的 for-in和 除外） | 
| 不繼續 | 不支援 continue。 | 
| 無生成器 | 不支援產生器。 | 
| 無產出 | 不支援 yield。 | 
| 無標籤 | 不支援標籤。 | 
| 否-此 | this 不支援 關鍵字。 | 
| 無嘗試 | 不支援 Try/catch 結構。 | 
| 無同時 | 雖然不支援迴圈。 | 
| no-disallowed-unary-operators | \$1\$1不允許 、 --和 \$1 unary 運算子。 | 
| no-disallowed-binary-operators | 不允許 instanceof運算子。 | 
| 無承諾 | 不支援非同步程序和承諾。 | 

**「plugin：@aws-appsync/recommended」**提供一些額外的規則，但也需要您將 TypeScript 組態新增至專案。


| 規則 | Description | 
| --- | --- | 
| 無遞迴 | 不允許遞迴函數呼叫。 | 
| no-disallowed-methods | 不允許某些方法。如需完整的支援內建函數，請參閱 [參考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)。 | 
| no-function-passing | 不允許將函數做為函數引數傳遞至函數。 | 
| no-function-reassign | 無法重新指派函數。 | 
| no-function-return | 函數不能是函數的傳回值。 | 

若要將外掛程式新增至您的專案，請遵循 [ ESLint 入門](https://eslint.org/docs/latest/user-guide/getting-started#installation-and-usage)中的安裝和使用步驟。然後，使用您的專案套件管理員在您的專案中安裝[外掛程式](https://www.npmjs.com/package/@aws-appsync/eslint-plugin) （例如 npm、 yarn 或 pnpm)：

```
$ npm install @aws-appsync/eslint-plugin
```

在您的 `.eslintrc.{js,yml,json}`檔案中，將**「plugin：@aws-appsync/base」**或**「plugin：@aws-appsync/recommended」**新增至 `extends` 屬性。以下程式碼片段是 JavaScript 的基本範例`.eslintrc`組態：

```
{
  "extends": ["plugin:@aws-appsync/base"]
}
```

若要使用**「plugin：@aws-appsync/recommended」**規則集，請安裝必要的相依性：

```
$ npm install -D @typescript-eslint/parser
```

然後，建立 `.eslintrc.js` 檔案：

```
{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2018,
    "project": "./tsconfig.json"
  },
  "extends": ["plugin:@aws-appsync/recommended"]
}
```

# `APPSYNC_JS` 執行時間的綁定、TypeScript 和來源映射
<a name="additional-utilities"></a>

TypeScript 透過提供類型安全和早期錯誤偵測來增強 AWS AppSync 開發。您可以在本機撰寫 TypeScript 程式碼並將其轉換為 JavaScript，然後再與`APPSYNC_JS`執行時間搭配使用。程序從安裝 TypeScript 和為`APPSYNC_JS`環境設定 tsconfig.json 開始。然後，您可以使用 esbuild 等綁定工具來編譯和綁定程式碼。Amplify CLI 會從 GraphQL 結構描述產生類型，讓您可以在解析程式程式碼中使用這些類型。

只要符合`APPSYNC_JS`要求，您就可以在解析程式和函數程式碼中利用自訂和外部程式庫。綁定工具將程式碼合併為單一檔案以供使用 AWS AppSync。可以包含來源映射以協助偵錯。

## 利用程式庫並綁定程式碼
<a name="using-external-libraries"></a>

在解析程式和函數程式碼中，只要符合`APPSYNC_JS`要求，您就可以利用自訂程式庫和外部程式庫。這可讓您在應用程式中重複使用現有的程式碼。若要使用由多個檔案定義的程式庫，您必須使用綁定工具，例如 [esbuild](https://esbuild.github.io/)，將程式碼合併到單一檔案中，然後儲存到 AWS AppSync 解析程式或函數。

綁定程式碼時，請記住下列事項：
+ `APPSYNC_JS` 僅支援 ECMAScript 模組 (ESM)。
+ `@aws-appsync/*` 模組已整合至 `APPSYNC_JS` ，且不應與您的程式碼綁定。
+ `APPSYNC_JS` 執行時間環境類似於 NodeJS，因為該程式碼不會在瀏覽器環境中執行。
+ 您可以包含選用的來源映射。不過，請勿包含來源內容。

  若要進一步了解來源映射，請參閱[使用來源映射](#source-maps)。

例如，若要綁定位於 的解析程式程式碼`src/appsync/getPost.resolver.js`，您可以使用下列 esbuild CLI 命令：

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/getPost.resolver.js
```

## 建置程式碼並使用 TypeScript
<a name="working-with-typescript"></a>

[TypeScript](https://www.typescriptlang.org/) 是由 Microsoft 開發的一種程式設計語言，可提供 JavaScript 的所有功能以及 TypeScript 類型系統。您可以使用 TypeScript 撰寫安全類型的程式碼，並在建置時擷取錯誤和錯誤，再將程式碼儲存至 AWS AppSync。`@aws-appsync/utils` 套件已完全輸入。

`APPSYNC_JS` 執行時間不支援 TypeScript。您必須先將 TypeScript 程式碼轉換為`APPSYNC_JS`執行時間支援的 JavaScript 程式碼，才能將程式碼儲存到其中 AWS AppSync。您可以使用 TypeScript 在本機整合開發環境 (IDE) 中撰寫程式碼，但請注意，您無法在 AWS AppSync 主控台中建立 TypeScript 程式碼。

若要開始使用，請確定專案中已安裝 [TypeScript](https://www.typescriptlang.org/download)。然後，設定 TypeScript 轉編譯設定，以使用 [TSConfig](https://www.typescriptlang.org/tsconfig) 搭配`APPSYNC_JS`執行時間。以下是您可以使用的基本`tsconfig.json`檔案範例：

```
// tsconfig.json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
   "noEmit": true,
   "moduleResolution": "node",
  }
}
```

然後，您可以使用 esbuild 等綁定工具來編譯和綁定程式碼。例如，假設專案的 AWS AppSync 程式碼位於 `src/appsync`，您可以使用下列命令來編譯和綁定程式碼：

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/**/*.ts
```

### 使用 Amplify codegen
<a name="working-with-amplify-codegen"></a>

您可以使用 [Amplify CLI](https://docs.amplify.aws/cli/) 來產生結構描述的類型。從`schema.graphql`檔案所在的目錄中，執行下列命令並檢閱提示以設定您的 Codegen：

```
$  npx @aws-amplify/cli codegen add
```

若要在某些情況下 （例如，結構描述更新時） 重新產生您的程式碼，請執行下列命令：

```
$ npx @aws-amplify/cli codegen
```

然後，您可以在解析程式程式碼中使用產生的類型。例如，指定下列結構描述：

```
type Todo {
  id: ID!
  title: String!
  description: String
}

type Mutation {
  createTodo(title: String!, description: String): Todo
}

type Query {
  listTodos: Todo
}
```

您可以在下列範例 AWS AppSync 函數中使用產生的類型：

```
import { Context, util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'
import { CreateTodoMutationVariables, Todo } from './API' // codegen

export function request(ctx: Context<CreateTodoMutationVariables>) {
	ctx.args.description = ctx.args.description ?? 'created on ' + util.time.nowISO8601()
	return ddb.put<Todo>({ key: { id: util.autoId() }, item: ctx.args })
}

export function response(ctx) {
	return ctx.result as Todo
}
```

### 在 TypeScript 中使用通用
<a name="working-with-typescript-generics"></a>

您可以搭配多種提供的類型使用學名藥。例如，以下程式碼片段是一種`Todo`類型：

```
export type Todo = {
  __typename: "Todo",
  id: string,
  title: string,
  description?: string | null,
};
```

您可以為使用 的訂閱撰寫解析程式`Todo`。在您的 IDE 中，輸入定義和自動完成提示將引導您正確使用`toSubscriptionFilter`轉換公用程式：

```
import { util, Context, extensions } from '@aws-appsync/utils'
import { Todo } from './API'

export function request(ctx: Context) {
  return {}
}

export function response(ctx: Context) {
  const filter = util.transform.toSubscriptionFilter<Todo>({
    title: { beginsWith: 'hello' },
    description: { contains: 'created' },
  })
  extensions.setSubscriptionFilter(filter)
  return null
}
```

## 內嵌您的套件
<a name="using-lint-with-bundles"></a>

您可以透過匯入 `esbuild-plugin-eslint` 外掛程式自動繫結套件。然後，您可以提供啟用隱含功能`plugins`的值來啟用它。以下是在名為 的檔案中使用 esbuild JavaScript API 的程式碼片段`build.mjs`：

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

## 使用來源映射
<a name="source-maps"></a>

您可以使用 JavaScript 程式碼提供內嵌來源映射 (`sourcemap`)。當您綁定 JavaScript 或 TypeScript 程式碼，並想要在日誌和執行時間 JavaScript 錯誤訊息中查看對輸入來源檔案的參考時，來源映射非常有用。

您的 `sourcemap` 必須出現在程式碼的結尾。它由遵循下列格式的單一註解行定義：

```
//# sourceMappingURL=data:application/json;base64,<base64 encoded string>
```

範例如下：

```
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibGliLmpzIiwgImNvZGUuanMiXSwKICAibWFwcGluZ3MiOiAiO0FBQU8sU0FBUyxRQUFRO0FBQ3RCLFNBQU87QUFDVDs7O0FDRE8sU0FBUyxRQUFRLEtBQUs7QUFDM0IsU0FBTyxNQUFNO0FBQ2Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
```

您可以使用 esbuild 建立來源映射。以下範例說明如何在建置和綁定程式碼時，使用 esbuild JavaScript API 來包含內嵌來源映射：

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  sourcemap: 'inline',
  sourcesContent: false,
  
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

特別是， `sourcemap`和 `sourcesContent`選項指定應該在每個組建結束時逐行新增來源映射，但不應包含來源內容。作為慣例，我們建議您不要在 中包含來源內容`sourcemap`。您可以將 `sources-content`設定為 ，在 esbuild 中停用此功能`false`。

若要說明來源映射的運作方式，請檢閱下列解析程式程式碼參考協助程式程式庫中協助程式函數的範例。此程式碼包含解析程式程式碼和協助程式程式程式庫中的日誌陳述式：

**./src/default.resolver.ts** （您的解析程式）

```
import { Context } from '@aws-appsync/utils'
import { hello, logit } from './helper'

export function request(ctx: Context) {
  console.log('start >')
  logit('hello world', 42, true)
  console.log('< end')
  return 'test'
}

export function response(ctx: Context): boolean {
  hello()
  return ctx.prev.result
}
```

**.src/helper.ts** （協助程式檔案）

```
export const logit = (...rest: any[]) => {
  // a special logger
  console.log('[logger]', ...rest.map((r) => `<${r}>`))
}

export const hello = () => {
  // This just returns a simple sentence, but it could do more.
  console.log('i just say hello..')
}
```

當您建置和綁定解析程式檔案時，您的解析程式程式碼將包含內嵌來源映射。當您的解析程式執行時，以下項目會出現在 CloudWatch 日誌中：

![\[CloudWatch log entries showing resolver code execution with inline source map information.\]](http://docs.aws.amazon.com/zh_tw/appsync/latest/devguide/images/cloudwatch-sourcemap.jpeg)


查看 CloudWatch 日誌中的項目，您會注意到這兩個檔案的功能已綁定在一起並同時執行。每個檔案的原始檔案名稱也會清楚地反映在日誌中。

# 在 中測試您的解析程式和函數處理常式 AWS AppSync
<a name="test-resolvers"></a>

您可以使用 `EvaluateCode` API 命令，在將程式碼儲存到解析程式或函數之前，使用模擬資料遠端測試解析程式和函數處理常式。若要開始使用 命令，請確定您已將 `appsync:evaluatecode`許可新增至政策。例如：

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "appsync:evaluateCode",
            "Resource": "arn:aws:appsync:us-east-1:111122223333:*"
        }
    ]
}
```

------

您可以使用 [AWS CLI ](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/index.html)或 [AWS SDKs](https://aws.amazon.com/tools/) 來利用 命令。例如，若要使用 CLI 測試程式碼，只需指向 檔案、提供內容，並指定您要評估的處理常式：

```
aws appsync evaluate-code \
  --code file://code.js \
  --function request \
  --context file://context.json \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0
```

回應包含 ，`evaluationResult`其中包含處理常式傳回的承載。它還包含物件，該`logs`物件會保留您的處理常式在評估期間產生的日誌清單。這可讓您輕鬆地偵錯程式碼執行，並查看評估的相關資訊，以協助故障診斷。例如：

```
{
    "evaluationResult": "{\"operation\":\"PutItem\",\"key\":{\"id\":{\"S\":\"record-id\"}},\"attributeValues\":{\"owner\":{\"S\":\"John doe\"},\"expectedVersion\":{\"N\":2},\"authorId\":{\"S\":\"Sammy Davis\"}}}",
    "logs": [
        "INFO - code.js:5:3: \"current id\" \"record-id\"",
        "INFO - code.js:9:3: \"request evaluated\""
    ]
}
```

評估結果可以剖析為 JSON，其提供：

```
{
  "operation": "PutItem",
  "key": {
    "id": {
      "S": "record-id"
    }
  },
  "attributeValues": {
    "owner": {
      "S": "John doe"
    },
    "expectedVersion": {
      "N": 2
    },
    "authorId": {
      "S": "Sammy Davis"
    }
  }
}
```

使用 SDK，您可以輕鬆整合測試套件中的測試，以驗證程式碼的行為。此處的範例使用 [Jest 測試架構](https://jestjs.io/)，但任何測試套件皆可運作。下列程式碼片段顯示假設性驗證執行。請注意，我們預期評估回應是有效的 JSON，因此我們使用 從字串回應`JSON.parse`擷取 JSON：

```
const AWS = require('aws-sdk')
const fs = require('fs')
const client = new AWS.AppSync({ region: 'us-east-2' })
const runtime = {name:'APPSYNC_JS',runtimeVersion:'1.0.0')

test('request correctly calls DynamoDB', async () => {
  const code = fs.readFileSync('./code.js', 'utf8')
  const context = fs.readFileSync('./context.json', 'utf8')
  const contextJSON = JSON.parse(context)
  
  const response = await client.evaluateCode({ code, context, runtime, function: 'request' }).promise()
  const result = JSON.parse(response.evaluationResult)
  
  expect(result.key.id.S).toBeDefined()
  expect(result.attributeValues.firstname.S).toEqual(contextJSON.arguments.firstname)
})
```

這會產生下列結果：

```
Ran all test suites.
> jest

PASS ./index.test.js
✓ request correctly calls DynamoDB (543 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 totalTime: 1.511 s, estimated 2 s
```

# 在 中從 VTL 遷移至 JavaScript AWS AppSync
<a name="migrating-resolvers"></a>

AWS AppSync 可讓您使用 VTL 或 JavaScript 為您的解析程式和函數撰寫商業邏輯。使用這兩種語言時，您會撰寫邏輯，指示 AWS AppSync 服務如何與資料來源互動。使用 VTL，您撰寫的映射範本必須評估為有效的 JSON 編碼字串。使用 JavaScript，您可以撰寫傳回物件的請求和回應處理常式。您不會傳回 JSON 編碼字串。

例如，採用下列 VTL 映射範本來取得 Amazon DynamoDB 項目：

```
{
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.args.id),
    }
}
```

公用程式`$util.dynamodb.toDynamoDBJson`會傳回 JSON 編碼字串。如果 `$ctx.args.id` 設定為 `<id>`，範本會評估為有效的 JSON 編碼字串：

```
{
    "operation": "GetItem",
    "key": {
        "id": {"S": "<id>"},
    }
}
```

使用 JavaScript 時，您不需要在程式碼中列印原始 JSON 編碼字串，而且`toDynamoDBJson`不需要像 一樣使用公用程式。上述映射範本的同等範例為：

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'GetItem',
    key: {id: util.dynamodb.toDynamoDB(ctx.args.id)}
  };
}
```

另一種方法是使用 `util.dynamodb.toMapValues`，這是處理值物件的建議方法：

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'GetItem',
    key: util.dynamodb.toMapValues({ id: ctx.args.id }),
  };
}
```

這會評估為：

```
{
  "operation": "GetItem",
  "key": {
    "id": {
      "S": "<id>"
    }
  }
}
```

**注意**  
我們建議您搭配 DynamoDB 資料來源使用 DynamoDB 模組：  

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	ddb.get({ key: { id: ctx.args.id } })
}
```

另一個範例是採用下列映射範本，將項目放入 Amazon DynamoDB 資料來源中：

```
{
    "operation" : "PutItem",
    "key" : {
        "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
```

評估時，此映射範本字串必須產生有效的 JSON 編碼字串。使用 JavaScript 時，您的程式碼會直接傳回請求物件：

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { id = util.autoId(), ...values } = ctx.args;
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ id }),
    attributeValues: util.dynamodb.toMapValues(values),
  };
}
```

評估為：

```
{
  "operation": "PutItem",
  "key": {
    "id": { "S": "2bff3f05-ff8c-4ed8-92b4-767e29fc4e63" }
  },
  "attributeValues": {
    "firstname": { "S": "Shaggy" },
    "age": { "N": 4 }
  }
}
```

**注意**  
我們建議您搭配 DynamoDB 資料來源使用 DynamoDB 模組：  

```
import { util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	const { id = util.autoId(), ...item } = ctx.args
	return ddb.put({ key: { id }, item })
}
```

# 在直接資料來源存取和透過 Lambda 資料來源代理之間進行選擇
<a name="choosing-data-source"></a>

透過 AWS AppSync 和`APPSYNC_JS`執行時間，您可以使用 AWS AppSync 函數存取資料來源，撰寫自己的程式碼來實作自訂商業邏輯。這可讓您輕鬆地直接與資料來源互動，例如 Amazon DynamoDB、Aurora Serverless、OpenSearch Service、HTTP APIs 和其他 AWS 服務，而無需部署額外的運算服務或基礎設施。 AWS AppSync 也可透過設定 Lambda 資料來源，輕鬆與 AWS Lambda 函數互動。Lambda 資料來源可讓您使用 AWS Lambda的完整集功能來執行複雜的商業邏輯，以解決 GraphQL 請求。在大多數情況下，直接連接到其目標資料來源的 an AWS AppSync 函數將提供您需要的所有功能。在您需要實作`APPSYNC_JS`執行時間不支援的複雜商業邏輯的情況下，您可以使用 Lambda 資料來源做為代理來與目標資料來源互動。


|  |  |  | 
| --- |--- |--- |
|  | 直接資料來源整合 | Lambda 資料來源做為代理 | 
| 使用案例 | AWS AppSync functions interact directly with API data sources. | AWS AppSync functions call Lambdas that interact with API data sources. | 
| Runtime | APPSYNC\$1JS (JavaScript) | 任何支援的 Lambda 執行時間 | 
| Maximum size of code | per AWS AppSync 函數 32，000 個字元 | 每個 Lambda 50 MB （壓縮，用於直接上傳） | 
| External modules | 有限 - 僅限 APPSYNC\$1JS 支援的功能 | 是 | 
| Call any AWS service | 是 - Using AWS AppSync HTTP 資料來源 | 是 - 使用 AWS SDK | 
| Access to the request header | 是 | 是 | 
| Network access | 否 | 是 | 
| File system access | 否 | 是 | 
| Logging and metrics | 是 | 是 | 
| Build and test entirely within AppSync | 是 | 否 | 
| Cold start | 否 | 否 - 使用佈建並行 | 
| Auto-scaling | 是 - 透明地 by AWS AppSync | 是 - 如 Lambda 中所設定 | 
| Pricing | 不收取其他費用 | 按 Lambda 用量收費 | 

直接與其目標資料來源整合的AWS AppSync 函數非常適合下列使用案例：
+  與 Amazon DynamoDB、Aurora Serverless 和 OpenSearch Service 互動
+  與 HTTP APIs 互動並傳遞傳入標頭 
+  使用 HTTP 資料來源與 AWS 服務互動 （使用提供的資料來源角色 AWS AppSync 自動簽署請求） 
+  在存取資料來源之前實作存取控制 
+  在履行請求之前，實作擷取資料的篩選 
+  在解析程式管道中以循序執行 AWS AppSync 函數來實作簡單的協同運作 
+  在查詢和變動中控制快取和訂閱連線。

使用 Lambda 資料來源做為代理的AWS AppSync 函數非常適合下列使用案例：
+  使用 JavaScript 或速度範本語言 (VTL) 以外的語言 
+  調整和控制 CPU 或記憶體以最佳化效能 
+  在 中匯入第三方程式庫或需要不支援的功能 `APPSYNC_JS` 
+  提出多個網路請求和/或取得檔案系統存取權以滿足查詢 
+  使用批次處理[組態批次處理](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-lambda-js.html)請求。

# AWS AppSync JavaScript 解析程式內容物件參考
<a name="resolver-context-reference-js"></a>

AWS AppSync 定義了一組變數和函數，用於處理請求和回應處理常式。這樣可讓使用 GraphQL 對資料進行邏輯運算更簡單。本文件說明這些函數並提供範例。

## 正在存取 `context`
<a name="accessing-the-context-js"></a>

請求和回應處理常式的`context`引數是物件，可保留解析程式調用的所有內容資訊。其結構如下：

```
type Context = {
  arguments: any;
  args: any;
  identity: Identity;
  source: any;
  error?: {
    message: string;
    type: string;
  };
  stash: any;
  result: any;
  prev: any;
  request: Request;
  info: Info;
};
```

**注意**  
您通常會發現`context`物件稱為 `ctx`。

`context` 物件中的每個欄位定義如下：

### `context` 欄位
<a name="accessing-the-context-list-js"></a>

** `arguments` **  
包含此欄位所有 GraphQL 引數的映射。

** `identity` **  
包含有關發起人資訊的物件。如需此欄位結構的詳細資訊，請參閱[身分](#aws-appsync-resolver-context-reference-identity-js)。

** `source` **  
包含父欄位解析度的映射。

** `stash` **  
堆疊是在每個解析程式和函數處理常式內提供的物件。相同的 stash 物件透過單一解析程式執行來存留。這表示您可以使用 stash 跨請求和回應處理常式，以及管道解析程式中的函數傳遞任意資料。  
您無法刪除或取代整個停止，但您可以新增、更新、刪除和讀取停止的屬性。
您可以修改下列其中一個程式碼範例，將項目新增至堆疊：  

```
//Example 1
ctx.stash.newItem = { key: "something" }

//Example 2
Object.assign(ctx.stash, {key1: value1, key2: value})
```
您可以修改以下程式碼，從堆疊中移除項目：  

```
delete ctx.stash.key
```

** `result` **  
此解析程式結果的容器。此欄位僅適用於回應處理常式。  
例如，如果您要解決下列查詢`author`的欄位：  

```
query {
    getPost(id: 1234) {
        postId
        title
        content
        author {
            id
            name
        }
    }
}
```
然後，評估回應處理常式時，即可使用完整`context`變數：  

```
{
  "arguments" : {
    id: "1234"
  },
  "source": {},
  "result" : {
      "postId": "1234",
      "title": "Some title",
      "content": "Some content",
      "author": {
        "id": "5678",
        "name": "Author Name"
      }
  },
  "identity" : {
      "sourceIp" : ["x.x.x.x"],
      "userArn" : "arn:aws:iam::123456789012:user/appsync",
      "accountId" : "666666666666",
      "user" : "AIDAAAAAAAAAAAAAAAAAA"
  }
}
```

** `prev.result` **  
在管道解析程式中執行任何先前操作的結果。  
如果先前的操作是管道解析程式的請求處理常式，則 `ctx.prev.result`代表該評估結果，並可供管道中的第一個函數使用。  
如果先前的操作是第一個函數，則 `ctx.prev.result` 代表第一個函數回應處理常式的評估結果，並可供管道中的第二個函數使用。  
如果先前的操作是最後一個函數，則 `ctx.prev.result` 代表最後一個函數的評估結果，並可供管道解析程式的回應處理常式使用。

** `info` **  
包含有關 GraphQL 請求資訊的物件。如需此欄位的結構，請參閱[資訊](#aws-appsync-resolver-context-reference-info-js)。

### Identity
<a name="aws-appsync-resolver-context-reference-identity-js"></a>

包含有關發起人資訊的 `identity` 區段。本節的形狀取決於 AWS AppSync API 的授權類型。

如需 AWS AppSync 安全選項的詳細資訊，請參閱[授權和身分驗證](security-authz.md#aws-appsync-security)。

** `API_KEY` 授權**  
`identity` 欄位未填入。

**`AWS_LAMBDA` 授權**  
`identity` 的格式如下：  

```
type AppSyncIdentityLambda = {
  resolverContext: any;
};
```
`identity` 包含 `resolverContext`金鑰，其中包含由授權請求的 Lambda 函數傳回的相同`resolverContext`內容。

** `AWS_IAM` 授權**  
`identity` 的格式如下：  

```
type AppSyncIdentityIAM = {
  accountId: string;
  cognitoIdentityPoolId: string;
  cognitoIdentityId: string;
  sourceIp: string[];
  username: string;
  userArn: string;
  cognitoIdentityAuthType: string;
  cognitoIdentityAuthProvider: string;
};
```

** `AMAZON_COGNITO_USER_POOLS` 授權**  
`identity` 的格式如下：  

```
type AppSyncIdentityCognito = {
  sourceIp: string[];
  username: string;
  groups: string[] | null;
  sub: string;
  issuer: string;
  claims: any;
  defaultAuthStrategy: string;
};
```

每個欄位的定義如下：

** `accountId` **  
發起人 AWS 的帳戶 ID。

** `claims` **  
使用者擁有的宣告。

** `cognitoIdentityAuthType` **  
經身分驗證或未經身分驗證 (根據身分類型)。

** `cognitoIdentityAuthProvider` **  
以逗號分隔的外部身分提供者資訊清單，用於取得用於簽署請求的登入資料。

** `cognitoIdentityId` **  
發起人的 Amazon Cognito 身分 ID。

** `cognitoIdentityPoolId` **  
與發起人相關聯的 Amazon Cognito 身分集區 ID。

** `defaultAuthStrategy` **  
此發起人 (`ALLOW` 或 `DENY`) 的預設授權策略。

** `issuer` **  
字符發行者。

** `sourceIp` **  
 AWS AppSync 接收的發起人的來源 IP 地址。如果請求不包含 `x-forwarded-for`標頭，來源 IP 值只會包含來自 TCP 連線的單一 IP 地址。如果要求包含 `x-forwarded-for` 標頭，則來源 IP 除了有 TCP 連線的 IP 地址外，也將有 `x-forwarded-for` 標頭中 IP 地址的清單。

** `sub` **  
已驗證使用者的 UUID。

** `user` **  
IAM 使用者。

** `userArn` **  
IAM 使用者的 Amazon Resource Name (ARN)。

** `username` **  
已驗證使用者的使用者名稱。如果是 `AMAZON_COGNITO_USER_POOLS` 授權，*使用者名稱*的值是屬性 *cognito:username* 的值。在`AWS_IAM`授權的情況下，*使用者名稱*的值是 AWS 使用者主體的值。如果您使用 IAM 授權搭配來自 Amazon Cognito 身分集區的憑證，我們建議您使用 `cognitoIdentityId`。

### 存取請求標頭
<a name="aws-appsync-resolver-context-reference-util-js"></a>

AWS AppSync 支援從用戶端傳遞自訂標頭，並使用 在 GraphQL 解析程式中存取它們`ctx.request.headers`。然後，您可以將 標頭值用於動作，例如將資料插入資料來源或授權檢查。您可以將 與來自命令列的 API 金鑰`$curl`搭配使用的單一或多個請求標頭，如下列範例所示：

**單一標頭範例** 

假設您設定使用 `custom` 值的 `nadia` 標頭，如下所示：

```
curl -XPOST -H "Content-Type:application/graphql" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
```

可使用 `ctx.request.headers.custom` 對此進行存取。例如，它可能位於 DynamoDB 的下列程式碼中：

```
"custom": util.dynamodb.toDynamoDB(ctx.request.headers.custom)
```

**多個標頭範例** 

您也可以在單一請求中傳遞多個標頭，並在解析程式處理常式中存取這些標頭。例如，如果 `custom`標頭設定為兩個值：

```
curl -XPOST -H "Content-Type:application/graphql" -H "custom:bailey" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
```

然後，您可以將這些存取為陣列，例如 `ctx.request.headers.custom[1]`。

**注意**  
AWS AppSync 不會在 中公開 Cookie 標頭`ctx.request.headers`。

### 存取請求自訂網域名稱
<a name="aws-access-requested-custom-domain-names-js"></a>

AWS AppSync 支援設定自訂網域，您可以用來存取 APIs的 GraphQL 和即時端點。使用自訂網域名稱提出請求時，您可以使用 取得網域名稱`ctx.request.domainName`。

使用預設 GraphQL 端點網域名稱時，值為 `null`。

### 資訊
<a name="aws-appsync-resolver-context-reference-info-js"></a>

`info` 區段包含有關 GraphQL 請求的資訊。本節的格式如下：

```
type Info = {
  fieldName: string;
  parentTypeName: string;
  variables: any;
  selectionSetList: string[];
  selectionSetGraphQL: string;
};
```

每個欄位的定義如下：

** `fieldName` **  
目前正在解析的欄位名稱。

** `parentTypeName` **  
目前正在解析的欄位父類型名稱。

** `variables` **  
包含傳遞給 GraphQL 請求之所有變數的映射。

** `selectionSetList` **  
此清單表示 GraphQL 選取範圍中的欄位。別名的欄位僅由別名名稱參考，而非欄位名稱。以下範例詳細說明這一點。

** `selectionSetGraphQL` **  
此字串表示格式為 GraphQL 結構描述定義語言 (SDL) 的選取範圍。雖然片段不會合併到選取集，但會保留內嵌片段，如下列範例所示。

**注意**  
`JSON.stringify` 不會在字串序列化`selectionSetList`中包含 `selectionSetGraphQL`和 。您必須直接參考這些屬性。

例如，如果您解析下列查詢的 `getPost` 欄位：

```
query {
  getPost(id: $postId) {
    postId
    title
    secondTitle: title
    content
    author(id: $authorId) {
      authorId
      name
    }
    secondAuthor(id: "789") {
      authorId
    }
    ... on Post {
      inlineFrag: comments: {
        id
      }
    }
    ... postFrag
  }
}

fragment postFrag on Post {
  postFrag: comments: {
    id
  }
}
```

然後，處理處理常式時可用的完整`ctx.info`變數可能是：

```
{
  "fieldName": "getPost",
  "parentTypeName": "Query",
  "variables": {
    "postId": "123",
    "authorId": "456"
  },
  "selectionSetList": [
    "postId",
    "title",
    "secondTitle"
    "content",
    "author",
    "author/authorId",
    "author/name",
    "secondAuthor",
    "secondAuthor/authorId",
    "inlineFragComments",
    "inlineFragComments/id",
    "postFragComments",
    "postFragComments/id"
  ],
  "selectionSetGraphQL": "{\n  getPost(id: $postId) {\n    postId\n    title\n    secondTitle: title\n    content\n    author(id: $authorId) {\n      authorId\n      name\n    }\n    secondAuthor(id: \"789\") {\n      authorId\n    }\n    ... on Post {\n      inlineFrag: comments {\n        id\n      }\n    }\n    ... postFrag\n  }\n}"
}
```

`selectionSetList` 只會公開屬於目前類型的欄位。如果目前類型是界面或聯集，則只會公開屬於界面的所選欄位。例如，指定下列結構描述：

```
type Query {
    node(id: ID!): Node
}

interface Node {
    id: ID
}

type Post implements Node {
    id: ID
    title: String
    author: String
}

type Blog implements Node {
    id: ID
    title: String
    category: String
}
```

以及下列查詢：

```
query {
    node(id: "post1") {
        id
        ... on Post {
            title
        }

        ... on Blog {
            title
        }
    }
}
```

`ctx.info.selectionSetList` 以`Query.node`欄位解析度呼叫 時，只會`id`公開：

```
"selectionSetList": [
    "id"
]
```

# 解析程式和函數的AWS AppSync JavaScript 執行期功能
<a name="resolver-util-reference-js"></a>

`APPSYNC_JS` 執行時間環境提供類似於 [ECMAScript (ES) 6.0 版的功能。](https://262.ecma-international.org/6.0/)它支援其功能子集，並提供一些不屬於 ES 規格的其他方法 （公用程式）。下列主題列出所有支援的語言功能：
+  [ 支援的執行期功能 ](https://docs.aws.amazon.com/appsync/latest/devguide/supported-features.html) - 進一步了解支援的核心功能、基本物件、內建物件和函數等。
+  [ 內建公用程式 ](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html) - util 變數包含可協助您處理資料的一般公用程式方法。除非另行指定，否則所有公用程式皆使用 UTF-8 字元集。
+  [ 內建模組 ](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-modules-js.html) - 進一步了解內建模組如何協助撰寫 JavaScript 解析程式和函數。
+  [ 執行期公用程式 ](https://docs.aws.amazon.com/appsync/latest/devguide/runtime-utils-js.html) - 執行期程式庫提供公用程式來控制或修改解析程式和函數的執行期屬性。
+  [ util.time 中的時間協助程式 ](https://docs.aws.amazon.com/appsync/latest/devguide/time-helpers-in-util-time-js.html) - util.time 變數包含日期時間方法，可協助產生時間戳記、在日期時間格式之間轉換，以及剖析日期時間字串。日期時間格式的語法是以 [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) 為基礎，您可以參考以取得進一步的文件。
+  [ util.dynamodb 中的 DynamoDB 協助程式 ](https://docs.aws.amazon.com/appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html) - util.dynamodb 包含協助程式方法，可讓您更輕鬆地將資料寫入和讀取至 Amazon DynamoDB，例如自動類型映射和格式化。
+  [ util.http 中的 HTTP 協助程式 ](https://docs.aws.amazon.com/appsync/latest/devguide/http-helpers-in-utils-http-js.html) - util.http 公用程式提供可用於管理 HTTP 請求參數和新增回應標頭的協助程式方法。
+  [ util.transform 中的轉換協助程式 ](https://docs.aws.amazon.com/appsync/latest/devguide/transformation-helpers-in-utils-transform-js.html) - util.transform 包含協助程式方法，可讓您更輕鬆地對資料來源執行複雜的操作。
+  [ util.str 中的字串協助程式 ](https://docs.aws.amazon.com/appsync/latest/devguide/str-helpers-in-util-str-js.html) - util.str 包含有助於常見字串操作的方法。
+  [ 延伸模組 ](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html) - 延伸模組包含一組方法，可在解析程式中執行其他動作。
+  [ util.xml 中的 XML 協助程式 ](https://docs.aws.amazon.com/appsync/latest/devguide/xml-helpers-in-util-xml-js.html) - util.xml 包含有助於 XML 字串轉換的方法。

**注意**  
目前，此參考僅適用於執行時間 **1.0.0** 版。

# 支援的執行時間功能
<a name="supported-features"></a>

以下各節說明 APPSYNC\$1JS 執行時間的支援功能集。

## 核心功能
<a name="core-features"></a>

支援下列核心功能。

------
#### [ Types ]

以下是支援的類型：
+ 數字
+ 字串
+ 布林值
+ objects
+ 陣列
+ 函數

------
#### [ Operators ]

支援運算子，包括：
+ 標準數學運算子 (`+`、`-`、`/``%`、、 `*`等）
+ nullish coalescing 運算子 (`??`)
+ 選用鏈結 (`?.`)
+ 位元運算子
+ `void` 和 `typeof` 運算子
+ 分散運算子 (`...`)

不支援下列運算子：
+ 統一運算子 `++`(`--`、 和 `~`)
+ `in`運算子
**注意**  
使用 `Object.hasOwn` 運算子來檢查指定的屬性是否位於指定的物件中。

------
#### [ Statements ]

支援下列陳述式：
+ `const`
+ `let`
+ `var`
+ `break`
+ `else`
+ `for-in`
+ `for-of` 
+ `if`
+ `return`
+ `switch`
+ 分散語法

不支援下列項目：
+ `catch`
+ `continue`
+ `do-while`
+ `finally`
+ `for(initialization; condition; afterthought)`
**注意**  
支援的例外是 `for-in`和 `for-of`表達式。
+ `throw`
+ `try`
+ `while`
+ 標籤陳述式

------
#### [ Literals ]

支援下列 ES 6 [範本常值](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)：
+ 多行字串
+ 表達式插補
+ 巢狀化範本

------
#### [ Functions ]

支援下列函數語法：
+ 支援函數宣告。
+ 支援 ES 6 箭頭函數。
+ 支援 ES 6 靜態參數語法。

------
#### [ Strict mode ]

函數按預設會在嚴格模式下運作，因此您不需要在函數程式碼中新增 `use_strict` 陳述式。無法對此進行變更。

------

## 基本物件
<a name="primitive-objects"></a>

支援以下基本的 ES 物件及其函數。

------
#### [ Object ]

支援下列物件：
+ `Object.assign()`
+ `Object.entries()` 
+ `Object.hasOwn()`
+ `Object.keys()` 
+ `Object.values()`
+ `delete` 

------
#### [ String ]

支援下列字串：
+  `String.prototype.length()` 
+  `String.prototype.charAt()` 
+  `String.prototype.concat()` 
+  `String.prototype.endsWith()` 
+  `String.prototype.indexOf()` 
+  `String.prototype.lastIndexOf()` 
+  `String.raw()` 
+  `String.prototype.replace()`
**注意**  
不支援規則運算式。  
不過，提供的參數中支援 Java 樣式的規則表達式建構。如需詳細資訊，請參閱[模式](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)。
+ `String.prototype.replaceAll()`
**注意**  
不支援規則運算式。  
不過，提供的參數中支援 Java 樣式的規則表達式建構。如需詳細資訊，請參閱[模式](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)。
+  `String.prototype.slice()` 
+  `String.prototype.split()` 
+  `String.prototype.startsWith()` 
+  `String.prototype.toLowerCase()` 
+  `String.prototype.toUpperCase()` 
+  `String.prototype.trim()` 
+  `String.prototype.trimEnd()` 
+  `String.prototype.trimStart()` 

------
#### [ Number ]

支援下列號碼：
+  `Number.isFinite` 
+  `Number.isNaN` 

------

## 內建物件和函數
<a name="built-in-objects-functions"></a>

支援下列函數和物件。

------
#### [ Math ]

支援下列數學函數：
+  `Math.random()` 
+  `Math.min()` 
+  `Math.max()` 
+  `Math.round()` 
+  `Math.floor()` 
+  `Math.ceil()` 

------
#### [ Array ]

支援下列陣列方法：
+ `Array.prototype.length` 
+ `Array.prototype.concat()` 
+ `Array.prototype.fill()` 
+ `Array.prototype.flat()` 
+ `Array.prototype.indexOf()` 
+ `Array.prototype.join()` 
+ `Array.prototype.lastIndexOf()` 
+ `Array.prototype.pop()` 
+ `Array.prototype.push()` 
+ `Array.prototype.reverse()` 
+ `Array.prototype.shift()` 
+ `Array.prototype.slice()` 
+ `Array.prototype.sort()`
**注意**  
`Array.prototype.sort()` 不支援引數。
+ `Array.prototype.splice()` 
+ `Array.prototype.unshift()`
+ `Array.prototype.forEach()`
+ `Array.prototype.map()`
+ `Array.prototype.flatMap()`
+ `Array.prototype.filter()`
+ `Array.prototype.reduce()`
+ `Array.prototype.reduceRight()`
+ `Array.prototype.find()`
+ `Array.prototype.some()`
+ `Array.prototype.every()`
+ `Array.prototype.findIndex()`
+ `Array.prototype.findLast()`
+ `Array.prototype.findLastIndex()`
+ `delete` 

------
#### [ Console ]

主控台物件可用於偵錯。在即時查詢執行期間，主控台日誌/錯誤陳述式會傳送至 Amazon CloudWatch Logs （如果啟用記錄功能）。使用 進行程式碼評估期間`evaluateCode`，日誌陳述式會在命令回應中傳回。
+ `console.error()`
+ `console.log()`

------
#### [ Function ]
+ 不支援 `bind`、 `apply`和 `call`方法。
+ 不支援函數建構子。
+ 不支援將函數做為引數傳遞。
+ 不支援遞迴函數呼叫。

------
#### [ JSON ]

支援下列 JSON 方法：
+ `JSON.parse()`
**注意**  
如果剖析的字串不是有效的 JSON，則傳回空白字串。
+ `JSON.stringify()`

------
#### [ Promises ]

不支援非同步程序，也不支援 promise。

**注意**  
在 in. `APPSYNC_JS`執行時間內不支援網路和檔案系統存取 AWS AppSync。 會根據 AWS AppSync 解析程式或 AWS AppSync 函數提出的請求 AWS AppSync 來處理所有 I/O 操作。

------

## 全域變數
<a name="globals"></a>

支援以下全局常數：
+  `NaN` 
+  `Infinity` 
+  `undefined`
+ [https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html)
+ [https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)
+ `runtime`

## 錯誤類型
<a name="error-types"></a>

`throw` 不支援使用 擲回錯誤。您可以使用 `util.error()`函數傳回錯誤。您可以使用 `util.appendError`函數在 GraphQL 回應中包含錯誤。

如需詳細資訊，請參閱[錯誤 utils](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html#utility-helpers-in-error-js)。

# 內建公用程式
<a name="built-in-util-js"></a>

`util` 變數包含可協助您處理資料的一般公用程式方法。除非另行指定，否則所有公用程式皆使用 UTF-8 字元集。

## 編碼 utils
<a name="utility-helpers-in-encoding"></a>

### 編碼 utils 清單
<a name="utility-helpers-in-encoding-list-js"></a>

 **`util.urlEncode(String)`**  
以 `application/x-www-form-urlencoded` 編碼字串的形式傳回輸入字串。

 **`util.urlDecode(String)`**  
將 `application/x-www-form-urlencoded` 編碼的字串解碼回非編碼格式。

**`util.base64Encode(string) : string`**  
將輸入編碼為 base64 編碼字串。

**`util.base64Decode(string) : string`**  
解碼 base64 編碼字串中的資料。

## ID 產生 utils
<a name="utility-helpers-in-id-gen-js"></a>

### ID 產生 utils 清單
<a name="utility-helpers-in-id-gen-list-js"></a>

 **`util.autoId()`**  
傳回 128 位元隨機產生的 UUID。

**`util.autoUlid()`**  
傳回 128 位元隨機產生的 ULID （通用可排序序列識別符）。

**`util.autoKsuid()`**  
傳回 128 位元隨機產生的 KSUID (K-Sortable Unique Identifier) base62，其編碼為長度為 27 的字串。

## 錯誤率
<a name="utility-helpers-in-error-js"></a>

### 錯誤使用率清單
<a name="utility-helpers-in-error-list-js"></a>

 **`util.error(String, String?, Object?, Object?)`**  
擲回自訂錯誤。如果範本偵測到要求或呼叫結果的錯誤，您可以將此用於要求或回應映射範本。此外，也可以指定 `errorType` 欄位、 `data` 欄位和 `errorInfo` 欄位。`data` 值將新增到 GraphQL 回應中，`error` 內對應的 `errors` 區塊。  
`data` 將根據查詢選取集進行篩選。`errorInfo` 值將新增到 GraphQL 回應中，`error` 內對應的 `errors` 區塊。  
`errorInfo` **不會**根據查詢選取集進行篩選。

 **`util.appendError(String, String?, Object?, Object?)`**  
附加自訂錯誤。如果範本偵測到要求或呼叫結果的錯誤，您可以將此用於要求或回應映射範本。此外，也可以指定 `errorType` 欄位、 `data` 欄位和 `errorInfo` 欄位。與 `util.error(String, String?, Object?, Object?)` 不同的是，範本評估不會受中斷，因此可以將資料傳回給發起人。`data` 值將新增到 GraphQL 回應中，`error` 內對應的 `errors` 區塊。  
`data` 將根據查詢選取集進行篩選。`errorInfo` 值將新增到 GraphQL 回應中，`error` 內對應的 `errors` 區塊。  
`errorInfo` **不會**根據查詢選取集進行篩選。

## 類型和模式比對 utils
<a name="utility-helpers-in-patterns-js"></a>

### 類型和模式比對 utils 清單
<a name="utility-helpers-in-patterns-js-list"></a>

**`util.matches(String, String) : Boolean`**  
如果第一個引數中指定的模式與第二個引數中提供的資料相符，則傳回真。模式必須為規則表達式，例如 `util.matches("a*b", "aaaaab")`。此功能是根據[模式](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)，您可以參考以取得更詳細的文件。

 **`util.authType()`**   
傳回描述請求所使用之多重驗證類型的字串，傳回「IAM 授權」、「使用者集區授權」、「開放式 ID Connect 授權」或「API 金鑰授權」。

## 傳回值行為 utils
<a name="utility-helpers-in-cloudwatch-logs-list-js"></a>

### 傳回值行為 utils 清單
<a name="utility-helpers-in-behavior-list-js"></a>

 **`util.escapeJavaScript(String)`**  
以 JavaScript 逸出字串傳回輸入字串。

## 解析程式授權公用程式
<a name="utility-helpers-in-resolver-auth-js"></a>

### 解析程式授權使用率清單
<a name="utility-helpers-in-resolver-auth-list-js"></a>

 **`util.unauthorized()`**  
擲回欲解析之欄位的 `Unauthorized`。在請求或回應映射範本中使用此選項，以決定是否允許發起人解析 欄位。

# 內建模組
<a name="built-in-modules-js"></a>

模組是`APPSYNC_JS`執行時間的一部分，並提供公用程式以協助撰寫 JavaScript 解析程式和函數。如需範例和範例，請參閱 [aws-appsync-resolver-samples](https://github.com/aws-samples/aws-appsync-resolver-samples) GitHub 儲存庫。

## DynamoDB 模組函數
<a name="built-in-ddb-modules"></a>

DynamoDB 模組函數可在與 DynamoDB 資料來源互動時提供增強的體驗。您可以使用 函數向 DynamoDB 資料來源提出請求，而無需新增類型映射。

使用 匯入模組`@aws-appsync/utils/dynamodb`：

```
// Modules are imported using @aws-appsync/utils/dynamodb
import * as ddb from '@aws-appsync/utils/dynamodb';
```

### 函數
<a name="built-in-ddb-modules-functions"></a>

#### 函數清單
<a name="built-in-ddb-modules-functions-list"></a>

 **` get<T>(payload: GetInput): DynamoDBGetItemRequest`**  
如需 GetInput 的相關資訊[輸入](#built-in-ddb-modules-inputs)，請參閱 。
產生`DynamoDBGetItemRequest`物件以向 DynamoDB 提出 [GetItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-getitem) 請求。  

```
import { get } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	return get({ key: { id: ctx.args.id } });
}
```

 **`put<T>(payload): DynamoDBPutItemRequest`**  
產生`DynamoDBPutItemRequest`物件以向 DynamoDB 提出 [PutItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem) 請求。  

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	return ddb.put({ key: { id: util.autoId() }, item: ctx.args });
}
```

**`remove<T>(payload): DynamoDBDeleteItemRequest`**  
產生`DynamoDBDeleteItemRequest`物件以向 DynamoDB 提出 [DeleteItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-deleteitem) 請求。  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	return ddb.remove({ key: { id: ctx.args.id } });
}
```

**`scan<T>(payload): DynamoDBScanRequest`**  
產生 `DynamoDBScanRequest`以向 DynamoDB 提出[掃描](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan)請求。  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const { limit = 10, nextToken } = ctx.args;
	return ddb.scan({ limit, nextToken });
}
```

**`sync<T>(payload): DynamoDBSyncRequest`**  
產生`DynamoDBSyncRequest`物件以提出[同步](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-sync)請求。請求只會接收自上次查詢後更改的資料 （差異更新）。只能對版本控制的 DynamoDB 資料來源提出請求。  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const { limit = 10, nextToken, lastSync } = ctx.args;
	return ddb.sync({ limit, nextToken, lastSync });
}
```

**`update<T>(payload): DynamoDBUpdateItemRequest`**  
產生`DynamoDBUpdateItemRequest`物件以向 DynamoDB 提出 [UpdateItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-updateitem) 請求。

### 作業
<a name="built-in-ddb-modules-operations"></a>

操作協助程式可讓您在更新期間對部分資料採取特定動作。若要開始使用，`operations`請從 匯入`@aws-appsync/utils/dynamodb`：

```
// Modules are imported using operations
import {operations} from '@aws-appsync/utils/dynamodb';
```

#### 操作清單
<a name="built-in-ddb-modules-operations-list"></a>

 **`add<T>(payload)`**  
在更新 DynamoDB 時新增屬性項目的協助程式函數。  
**範例**  
若要使用 ID 值將地址 （街道、城市和郵遞區號） 新增至現有的 DynamoDB 項目：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		address: operations.add({
			street1: '123 Main St',
			city: 'New York',
			zip: '10001',
		}),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`append <T>(payload)`**  
將承載附加至 DynamoDB 中現有清單的協助程式函數。  
**範例**  
若要在更新期間將新增IDs (`newFriendIds`) 附加至現有的朋友清單 (`friendsIds`)：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [101, 104, 111];
	const updateObj = {
		friendsIds: operations.append(newFriendIds),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`decrement (by?)`**  
在更新 DynamoDB 時減少項目中現有屬性值的協助程式函數。  
**範例**  
若要將朋友計數器 (`friendsCount`) 減少 10：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		friendsCount: operations.decrement(10),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`increment (by?)`**  
在更新 DynamoDB 時遞增項目中現有屬性值的協助程式函數。  
**範例**  
若要將好友計數器 (`friendsCount`) 增加 10：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		friendsCount: operations.increment(10),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`prepend <T>(payload)`**  
在 DynamoDB 中現有清單前面的協助程式函數。  
**範例**  
若要在更新期間將新增IDs (`newFriendIds`) 附加至現有的朋友清單 (`friendsIds`)：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [101, 104, 111];
	const updateObj = {
		friendsIds: operations.prepend(newFriendIds),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`replace <T>(payload)`**  
在 DynamoDB 中更新項目時取代現有屬性的協助程式函數。當您想要更新屬性中的整個物件或子物件，而不只是承載中的索引鍵時，此功能非常有用。  
**範例**  
若要取代 `info` 物件中的地址 （街道、城市和郵遞區號）：  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		info: {
			address: operations.replace({
				street1: '123 Main St',
				city: 'New York',
				zip: '10001',
			}),
		},
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`updateListItem <T>(payload, index)`**  
取代清單中項目的協助程式函數。  
**範例**  
在更新範圍 (`newFriendIds`) 中，此範例用於`updateListItem`更新清單中第二個項目 （索引：`1`，新 ID：`102`) 和第三個項目 （索引：`2`，新 ID：`112`) 的 ID 值 ()`friendsIds`。  

```
import { update, operations as ops } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [
		ops.updateListItem('102', 1), ops.updateListItem('112', 2)
	];
	const updateObj = { friendsIds: newFriendIds };
	return update({ key: { id: 1 }, update: updateObj });
}
```

### 輸入
<a name="built-in-ddb-modules-inputs"></a>

#### 輸入清單
<a name="built-in-ddb-modules-inputs-list"></a>

 **`Type GetInput<T>`**  

```
GetInput<T>: { 
    consistentRead?: boolean; 
    key: DynamoDBKey<T>; 
}
```
**類型宣告**  
+ `consistentRead?: boolean` (選用)

  選用布林值，用於指定是否要與 DynamoDB 執行強式一致讀取。
+ `key: DynamoDBKey<T>` (必要)

  在 DynamoDB 中指定項目索引鍵的必要參數。DynamoDB 項目可能有單一雜湊索引鍵或雜湊和排序索引鍵。

**`Type PutInput<T>`**  

```
PutInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T> | null; 
    customPartitionKey?: string; 
    item: Partial<T>; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
}
```
**類型宣告**  
+ `_version?: number` (選用)
+ `condition?: DynamoDBFilterObject<T> | null` (選用)

  當您將物件放入 DynamoDB 資料表時，您可以選擇指定條件式表達式，以根據在執行操作之前已在 DynamoDB 中的物件狀態來控制請求是否成功。
+ `customPartitionKey?: string` (選用)

  啟用時，此字串值會修改啟用版本控制時差異同步資料表所使用的 `ds_sk`和 `ds_pk` 記錄格式。啟用時，也會啟用`populateIndexFields`項目的處理。
+ `item: Partial<T>` (必要)

  要放入 DynamoDB 之項目的其餘屬性。
+ `key: DynamoDBKey<T>` (必要)

  必要參數，指定 DynamoDB 中要對其執行放置的項目索引鍵。DynamoDB 項目可能有單一雜湊索引鍵或雜湊和排序索引鍵。
+ `populateIndexFields?: boolean` (選用)

  布林值，當 與 啟用時`customPartitionKey`，會為差異同步資料表中的每個記錄建立新的項目，特別是在 `gsi_ds_pk`和 `gsi_ds_sk`欄中。如需詳細資訊，請參閱《 *AWS AppSync 開發人員指南*》中的[衝突偵測和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)。

**`Type QueryInput<T>`**  

```
QueryInput<T>: ScanInput<T> & { 
    query: DynamoDBKeyCondition<Required<T>>; 
}
```
**類型宣告**  
+ `query: DynamoDBKeyCondition<Required<T>>` (必要)

  指定描述要查詢之項目的金鑰條件。對於指定的索引，分割區索引鍵的條件應為等式，排序索引鍵應為比較或 `beginsWith`（當它是字串時）。分割區和排序索引鍵僅支援數字和字串類型。

  **範例**

  請採用以下`User`類型：

  ```
  type User = {
    id: string;
    name: string;
    age: number;
    isVerified: boolean;
    friendsIds: string[] 
  }
  ```

  查詢只能包含下列欄位：`id`、 `name`和 `age`：

  ```
  const query: QueryInput<User> = {
      name: { eq: 'John' },
      age: { gt: 20 },
  }
  ```

**`Type RemoveInput<T>`**  

```
RemoveInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T>; 
    customPartitionKey?: string; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
}
```
**類型宣告**  
+ `_version?: number` (選用)
+ `condition?: DynamoDBFilterObject<T>` (選用)

  當您在 DynamoDB 中移除物件時，您可以選擇指定條件式表達式，以根據在執行操作之前已在 DynamoDB 中的物件狀態來控制請求是否成功。

  **範例**

  下列範例是包含條件的`DeleteItem`表達式，只有在文件擁有者符合提出請求的使用者時，才會允許操作成功。

  ```
  type Task = {
    id: string;
    title: string;
    description: string;
    owner: string;
    isComplete: boolean;
  }
  const condition: DynamoDBFilterObject<Task> = {
    owner: { eq: 'XXXXXXXXXXXXXXXX' },
  }
  
  remove<Task>({
     key: {
       id: 'XXXXXXXXXXXXXXXX',
    },
    condition,
  });
  ```
+ `customPartitionKey?: string` (選用)

  啟用時， `customPartitionKey`值會修改啟用版本控制時差異同步資料表所使用的 `ds_sk`和 `ds_pk` 記錄格式。啟用時，也會啟用`populateIndexFields`項目的處理。
+ `key: DynamoDBKey<T>` (必要)

  必要參數，指定要移除之 DynamoDB 中項目的索引鍵。DynamoDB 項目可能有單一雜湊索引鍵或雜湊和排序索引鍵。

  **範例**

  如果`User`只有使用者 的雜湊金鑰`id`，則金鑰看起來會如下所示：

  ```
  type User = {
  	id: number
  	name: string
  	age: number
  	isVerified: boolean
  }
  const key: DynamoDBKey<User> = {
  	id: 1,
  }
  ```

  如果資料表使用者具有雜湊索引鍵 (`id`) 和排序索引鍵 (`name`)，則索引鍵看起來會如下所示：

  ```
  type User = {
  	id: number
  	name: string
  	age: number
  	isVerified: boolean
  	friendsIds: string[]
  }
  
  const key: DynamoDBKey<User> = {
  	id: 1,
  	name: 'XXXXXXXXXX',
  }
  ```
+ `populateIndexFields?: boolean` (選用)

  布林值，當 與 啟用時`customPartitionKey`，會為差異同步資料表中的每個記錄建立新的項目，特別是在 `gsi_ds_pk`和 `gsi_ds_sk`欄中。

**`Type ScanInput<T>`**  

```
ScanInput<T>: { 
    consistentRead?: boolean | null; 
    filter?: DynamoDBFilterObject<T> | null; 
    index?: string | null; 
    limit?: number | null; 
    nextToken?: string | null; 
    scanIndexForward?: boolean | null; 
    segment?: number; 
    select?: DynamoDBSelectAttributes; 
    totalSegments?: number; 
}
```
**類型宣告**  
+ `consistentRead?: boolean | null` (選用)

  在查詢 DynamoDB 時指出一致讀取的選用布林值。預設值為 `false`。
+ `filter?: DynamoDBFilterObject<T> | null` (選用)

  從資料表擷取結果後，要套用至結果的選用篩選條件。
+ `index?: string | null` (選用)

  要掃描的索引選用名稱。
+ `limit?: number | null` (選用)

  要傳回的選用結果數目上限。
+ `nextToken?: string | null` (選用)

  選用分頁字符，以繼續先前的查詢。這會是從先前查詢所取得的。
+ `scanIndexForward?: boolean | null` (選用)

  選用布林值，指出查詢是以遞增或遞減順序執行。依預設，此值是設為 `true`。
+ `segment?: number` (選用)
+ `select?: DynamoDBSelectAttributes` (選用)

  從 DynamoDB 傳回的屬性。根據預設， AWS AppSync DynamoDB 解析程式只會傳回投影到索引中的屬性。支援的值是：
  + `ALL_ATTRIBUTES`

    從指定的資料表或索引傳回所有項目屬性。如果您查詢本機次要索引，DynamoDB 會從索引中每個相符項目的父資料表擷取整個項目。如果索引設定為投射所有項目屬性，所有資料都可從本機次要索引取得，不需進行任何擷取。
  + `ALL_PROJECTED_ATTRIBUTES`

    傳回已投影至索引的所有屬性。如果索引設定為投射所有屬性，此傳回值相當於指定 `ALL_ATTRIBUTES`。
  + `SPECIFIC_ATTRIBUTES`

    僅傳回 中列出的屬性`ProjectionExpression`。此傳回值等同於指定 ，`ProjectionExpression`而不指定 的任何值`AttributesToGet`。
+ `totalSegments?: number` (選用)

**`Type DynamoDBSyncInput<T>`**  

```
DynamoDBSyncInput<T>: { 
    basePartitionKey?: string; 
    deltaIndexName?: string; 
    filter?: DynamoDBFilterObject<T> | null; 
    lastSync?: number; 
    limit?: number | null; 
    nextToken?: string | null; 
}
```
**類型宣告**  
+ `basePartitionKey?: string` (選用)

  執行同步操作時要使用之基底資料表的分割區索引鍵。此欄位允許在資料表使用自訂分割區索引鍵時執行 Sync 操作。
+ `deltaIndexName?: string` (選用)

  用於同步操作的索引。當資料表使用自訂分割區索引鍵時，需要此索引才能在整個差異存放區資料表上啟用同步操作。同步操作將在 GSI 上執行 （在 `gsi_ds_pk`和 上建立`gsi_ds_sk`)。
+ `filter?: DynamoDBFilterObject<T> | null` (選用)

  從資料表擷取結果後，要套用至結果的選用篩選條件。
+ `lastSync?: number` (選用)

  上次成功同步操作開始的時刻，以 epoch 毫秒為單位。如果指定此值，只會傳回 `lastSync` 之後變更的項目。只有在從初始同步操作擷取所有頁面之後，才應該填入此欄位。如果省略，則會傳回基礎資料表的結果。否則，將會傳回差異資料表的結果。
+ `limit?: number | null` (選用)

  要一次評估的選用項目數量上限。如果省略此值，預設限制將設為 `100` 個項目。此欄位的最大值為 `1000` 個項目。
+ `nextToken?: string | null` (選用)

**`Type DynamoDBUpdateInput<T>`**  

```
DynamoDBUpdateInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T>; 
    customPartitionKey?: string; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
    update: DynamoDBUpdateObject<T>; 
}
```
**類型宣告**  
+ `_version?: number` (選用)
+ `condition?: DynamoDBFilterObject<T>` (選用)

  當您更新 DynamoDB 中的物件時，您可以選擇指定條件式表達式，以根據在執行操作之前已在 DynamoDB 中的物件狀態來控制請求是否成功。
+ `customPartitionKey?: string` (選用)

  啟用時， `customPartitionKey`值會修改啟用版本控制時差異同步資料表所使用的 `ds_sk`和 `ds_pk` 記錄格式。啟用時，也會啟用`populateIndexFields`項目的處理。
+ `key: DynamoDBKey<T>` (必要)

  必要參數，指定正在更新的 DynamoDB 中項目的索引鍵。DynamoDB 項目可能有單一雜湊索引鍵或雜湊和排序索引鍵。
+ `populateIndexFields?: boolean` (選用)

  布林值，當 與 啟用時`customPartitionKey`，會為差異同步資料表中的每個記錄建立新的項目，特別是在 `gsi_ds_pk`和 `gsi_ds_sk`欄中。
+ `update: DynamoDBUpdateObject<T>`

  指定要更新的屬性及其新值的物件。更新物件可與 `add`、`remove`、、`replace``increment`、`decrement`、`append`、`prepend`、 搭配使用`updateListItem`。

## Amazon RDS 模組函數
<a name="built-in-rds-modules"></a>

Amazon RDS 模組函數可在與使用 Amazon RDS Data API 設定的資料庫互動時提供增強的體驗。使用 匯入模組`@aws-appsync/utils/rds`：

```
import * as rds from '@aws-appsync/utils/rds';
```

也可以個別匯入函數。例如，以下匯入使用 `sql`：

```
import { sql } from '@aws-appsync/utils/rds';
```

### 函數
<a name="built-in-rds-modules-functions"></a>

您可以使用 AWS AppSync RDS 模組的公用程式協助程式來與資料庫互動。

#### Select
<a name="built-in-rds-modules-functions-select"></a>

`select` 公用程式會建立 `SELECT`陳述式來查詢您的關聯式資料庫。

**基本使用**

以其基本形式，您可以指定要查詢的資料表：

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement: 
    // "SELECT * FROM "persons"
    return createPgStatement(select({table: 'persons'}));
}
```

請注意，您也可以在資料表識別符中指定結構描述：

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement:
    // SELECT * FROM "private"."persons"
    return createPgStatement(select({table: 'private.persons'}));
}
```

**指定資料欄**

您可以使用 `columns` 屬性指定資料欄。如果未將此值設定為 ，則預設為 `*`：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name']
    }));
}
```

您也可以指定資料欄的資料表：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "persons"."name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'persons.name']
    }));
}
```

**限制和位移**

您可以套用 `limit`和 `offset`至查詢：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name"
    // FROM "persons"
    // LIMIT :limit
    // OFFSET :offset
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        limit: 10,
        offset: 40
    }));
}
```

**排序依據**

您可以使用 `orderBy` 屬性排序結果。提供指定 欄和選用 `dir` 屬性的物件陣列：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name" FROM "persons"
    // ORDER BY "name", "id" DESC
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        orderBy: [{column: 'name'}, {column: 'id', dir: 'DESC'}]
    }));
}
```

**篩選條件**

您可以使用特殊條件物件來建置篩選條件：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}}
    }));
}
```

您也可以合併篩選條件：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME and "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}, id: {gt: 10}}
    }));
}
```

您也可以建立`OR`陳述式：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME OR "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { or: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

您也可以使用 否定條件`not`：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE NOT ("name" = :NAME AND "id" > :ID)
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { not: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

您也可以使用下列運算子來比較值：


| 
| 
| 運算子 | Description | 可能的值類型 | 
| --- |--- |--- |
| eq | Equal | number, string, boolean | 
| ne | Not equal | number, string, boolean | 
| le | Less than or equal | number, string | 
| lt | Less than | number, string | 
| ge | Greater than or equal | number, string | 
| gt | Greater than | number, string | 
| contains | Like | string | 
| notContains | Not like | string | 
| beginsWith | Starts with prefix | string | 
| between | Between two values | number, string | 
| attributeExists | The attribute is not null | number, string, boolean | 
| size | checks the length of the element | string | 

#### Insert
<a name="built-in-rds-modules-functions-insert"></a>

`insert` 公用程式提供使用 `INSERT`操作在資料庫中插入單一資料列項目的直接方式。

**單一項目插入**

若要插入項目，請指定 資料表，然後傳入值的物件。物件索引鍵會映射到您的資料表資料欄。資料欄名稱會自動逸出，並使用變數映射將值傳送至資料庫：

```
import { insert, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({ table: 'persons', values });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    return createMySQLStatement(insertStatement)
}
```

**MySQL 使用案例**

您可以結合 `insert`後接 `select`來擷取插入的資料列：

```
import { insert, select, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({  table: 'persons', values });
    const selectStatement = select({
        table: 'persons',
        columns: '*',
        where: { id: { eq: values.id } },
        limit: 1,
    });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    // and
    // SELECT *
    // FROM `persons`
    // WHERE `id` = :ID
    return createMySQLStatement(insertStatement, selectStatement)
}
```

**Postgres 使用案例**

使用 Postgres，您可以使用 從您插入的資料列[https://www.postgresql.org/docs/current/dml-returning.html](https://www.postgresql.org/docs/current/dml-returning.html)取得資料。它接受 `*`或一組資料欄名稱：

```
import { insert, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({
        table: 'persons',
        values,
        returning: '*'
    });

    // Generates statement:
    // INSERT INTO "persons"("name")
    // VALUES(:NAME)
    // RETURNING *
    return createPgStatement(insertStatement)
}
```

#### 更新
<a name="built-in-rds-modules-functions-update"></a>

`update` 公用程式可讓您更新現有的資料列。您可以使用 條件物件，將變更套用至滿足條件的所有資料列中的指定資料欄。例如，假設我們有一個結構描述，允許我們進行此變動。我們希望以 `Person` `id`的值更新 `name` 的 ，`3`但前提是我們從 開始知道它們 (`known_since`)`2000`：

```
mutation Update {
    updatePerson(
        input: {id: 3, name: "Jon"},
        condition: {known_since: {ge: "2000"}}
    ) {
    id
    name
  }
}
```

我們的更新解析程式如下所示：

```
import { update, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id, ...values }, condition } = ctx.args;
    const where = {
        ...condition,
        id: { eq: id },
    };
    const updateStatement = update({
        table: 'persons',
        values,
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // UPDATE "persons"
    // SET "name" = :NAME, "birthday" = :BDAY, "country" = :COUNTRY
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

我們可以將檢查新增至條件，以確保只會更新主索引鍵`id`等於 `3` 的資料列。同樣地，對於 Postgres `inserts`，您可以使用 `returning` 來傳回修改後的資料。

#### 移除
<a name="built-in-rds-modules-functions-remove"></a>

`remove` 公用程式可讓您刪除現有的資料列。您可以在滿足條件的所有資料列上使用條件物件。請注意， `delete` 是 JavaScript 中的預留關鍵字。 `remove` 應該改用：

```
import { remove, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id }, condition } = ctx.args;
    const where = { ...condition, id: { eq: id } };
    const deleteStatement = remove({
        table: 'persons',
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // DELETE "persons"
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

### 轉換
<a name="built-in-rds-modules-casting"></a>

在某些情況下，您可能希望在陳述式中使用有關正確物件類型的更具體性。您可以使用提供的類型提示來指定參數的類型。 AWS AppSync 支援與資料 API [相同的類型提示](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html#rdsdtataservice-Type-SqlParameter-typeHint)。您可以使用 模組的 `typeHint`函數來 AWS AppSync `rds`轉換參數。

下列範例可讓您將陣列做為值傳送，該值會轉換為 JSON 物件。我們使用 `->`運算子來擷取 JSON 陣列`index``2`中 的 元素：

```
import { sql, createPgStatement, toJsonObject, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const arr = ctx.args.list_of_ids
    const statement = sql`select ${typeHint.JSON(arr)}->2 as value`
    return createPgStatement(statement)
}

export function response(ctx) {
    return toJsonObject(ctx.result)[0][0].value
}
```

在處理和比較 `DATE`、 和 時`TIME`，投射也很有用`TIMESTAMP`：

```
import { select, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const when = ctx.args.when
    const statement = select({
        table: 'persons',
        where: { createdAt : { gt: typeHint.DATETIME(when) } }
    })
    return createPgStatement(statement)
}
```

以下另一個範例示範如何傳送目前的日期和時間：

```
import { sql, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const now = util.time.nowFormatted('YYYY-MM-dd HH:mm:ss')
    return createPgStatement(sql`select ${typeHint.TIMESTAMP(now)}`)
}
```

**可用的類型提示**
+ `typeHint.DATE` - 對應的參數會以 `DATE`類型的物件傳送至資料庫。接受的格式為 `YYYY-MM-DD`。
+ `typeHint.DECIMAL` - 對應的參數會以 `DECIMAL`類型的物件傳送至資料庫。
+ `typeHint.JSON` - 對應的參數會以 `JSON`類型的物件傳送至資料庫。
+ `typeHint.TIME` - 對應的字串參數值會以 `TIME`類型的物件傳送至資料庫。接受的格式為 `HH:MM:SS[.FFF]`。
+ `typeHint.TIMESTAMP` - 對應的字串參數值會以 `TIMESTAMP`類型的物件傳送至資料庫。接受的格式為 `YYYY-MM-DD HH:MM:SS[.FFF]`。
+ `typeHint.UUID` - 對應的字串參數值會以 `UUID`類型的物件傳送至資料庫。

# 執行期公用程式
<a name="runtime-utils-js"></a>

`runtime` 程式庫提供公用程式來控制或修改解析程式和函數的執行期屬性。

## 執行期 utils 清單
<a name="runtime-utils-list-js"></a>

 **`runtime.earlyReturn(obj?: unknown, returnOptions?: {skipTo: 'END' | 'NEXT'}): never`**  
根據目前的內容，叫用此函數會停止執行目前的處理常式、 AWS AppSync 函數或解析程式 （單位或管道解析程式）。系統會傳回指定的物件做為結果。  
+ 在 AWS AppSync 函數請求處理常式中呼叫 時，會略過資料來源和回應處理常式，並呼叫下一個函數請求處理常式 （如果這是最後一個 AWS AppSync 函數，則為管道解析程式回應處理常式）。
+ 在 AWS AppSync 管道解析程式請求處理常式中呼叫 時，會略過管道執行，並立即呼叫管道解析程式回應處理常式。
+ `returnOptions` 將 `skipTo` 設為 "END" 時，會略過管道執行，並立即呼叫管道解析程式回應處理常式。
+ `returnOptions` 將 `skipTo` 設為 "NEXT" 時，會略過函數執行，並呼叫下一個管道處理常式。
**範例**  

```
import { runtime } from '@aws-appsync/utils'

export function request(ctx) {
  runtime.earlyReturn({ hello: 'world' })
  // code below is not executed
  return ctx.args
}

// never called because request returned early
export function response(ctx) {
  return ctx.result
}
```

# util.time 中的時間協助程式
<a name="time-helpers-in-util-time-js"></a>

`util.time` 變數包含日期時間方法，可協助產生時間戳記、在日期時間格式之間轉換，以及剖析日期時間字串。日期時間格式的語法是根據 [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)，您可以參考以取得更詳細的文件。

## 時間使用率清單
<a name="utility-helpers-in-time-list-js"></a>

 **`util.time.nowISO8601()`**  
以 [ISO8601 格式](https://en.wikipedia.org/wiki/ISO_8601)傳回 UTC 的字串表示方式。

 **`util.time.nowEpochSeconds()`**  
傳回從 1970-01-01T00:00:00Z 的 epoch 到現在的秒數。

 **`util.time.nowEpochMilliSeconds()`**  
傳回從 1970-01-01T00:00:00Z 的 epoch 到現在的毫秒數。

 **`util.time.nowFormatted(String)`**  
使用字串輸入類型的指定格式，傳回 UTC 中目前時間戳記的字串。

 **`util.time.nowFormatted(String, String)`**  
使用字串輸入類型的指定格式和時區，傳回時區目前時間戳記的字串。

 **`util.time.parseFormattedToEpochMilliSeconds(String, String)`**  
剖析以字串形式傳遞的時間戳記，以及包含時區的格式，然後傳回自 epoch 以來以毫秒為單位的時間戳記。

 **`util.time.parseFormattedToEpochMilliSeconds(String, String, String)`**  
剖析以字串形式傳遞的時間戳記，以及格式和時區，然後以毫秒為單位傳回自 epoch 以來的時間戳記。

 **`util.time.parseISO8601ToEpochMilliSeconds(String)`**  
剖析以字串形式傳遞的 ISO8601 時間戳記，然後將時間戳記傳回為自 epoch 以來的毫秒。

 **`util.time.epochMilliSecondsToSeconds(long)`**  
將 epoch 毫秒時間戳記轉換為 epoch 秒時間戳記。

 **`util.time.epochMilliSecondsToISO8601(long)`**  
將 epoch 毫秒時間戳記轉換為 ISO8601 時間戳記。

 **`util.time.epochMilliSecondsToFormatted(long, String)`**  
將 epoch 毫秒時間戳記轉換為根據 UTC 格式提供的時間戳記。

 **`util.time.epochMilliSecondsToFormatted(long, String, String)`**  
將長傳遞的 epoch 毫秒時間戳記轉換為根據所提供時區中提供的格式格式化的時間戳記。

# util.dynamodb 中的 DynamoDB 協助程式
<a name="dynamodb-helpers-in-util-dynamodb-js"></a>

`util.dynamodb` 包含協助程式方法，可讓您更輕鬆地將資料寫入和讀取至 Amazon DynamoDB，例如自動類型映射和格式化。

## toDynamoDB
<a name="utility-helpers-in-toDynamoDB-js"></a>

### toDynamoDB 公用程式清單
<a name="utility-helpers-in-toDynamoDB-list-js"></a>

 **`util.dynamodb.toDynamoDB(Object)`**   
DynamoDB 的一般物件轉換工具，可將輸入物件轉換為適當的 DynamoDB 表示法。它在代表一些類型的方式上是固定的：例如，它會使用清單 (「L」) 而不是集合 (「SS」、「NS」、「BS」)。這會傳回描述 DynamoDB 屬性值的物件。  
**字串範例**  

```
Input:      util.dynamodb.toDynamoDB("foo")
Output:     { "S" : "foo" }
```
**數字範例**  

```
Input:      util.dynamodb.toDynamoDB(12345)
Output:     { "N" : 12345 }
```
**布林值範例**  

```
Input:      util.dynamodb.toDynamoDB(true)
Output:     { "BOOL" : true }
```
**清單範例**  

```
Input:      util.dynamodb.toDynamoDB([ "foo", 123, { "bar" : "baz" } ])
Output:     {
               "L" : [
                   { "S" : "foo" },
                   { "N" : 123 },
                   {
                       "M" : {
                           "bar" : { "S" : "baz" }
                       }
                   }
               ]
           }
```
**地圖範例**  

```
Input:      util.dynamodb.toDynamoDB({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "M" : {
                   "foo"  : { "S" : "bar" },
                   "baz"  : { "N" : 1234 },
                   "beep" : {
                       "L" : [
                           { "S" : "boop" }
                       ]
                   }
               }
           }
```

## toString utils
<a name="utility-helpers-in-toString-js"></a>

### toString utils 清單
<a name="utility-helpers-in-toString-list-js"></a>

**`util.dynamodb.toString(String)`**  
將輸入字串轉換為 DynamoDB 字串格式。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toString("foo")
Output:     { "S" : "foo" }
```

 **`util.dynamodb.toStringSet(List<String>)`**  
將具有字串的清單轉換為 DynamoDB 字串集格式。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toStringSet([ "foo", "bar", "baz" ])
Output:     { "SS" : [ "foo", "bar", "baz" ] }
```

## toNumber utils
<a name="utility-helpers-in-toNumber-js"></a>

### toNumber utils 清單
<a name="utility-helpers-in-toNumber-list-js"></a>

 **`util.dynamodb.toNumber(Number)`**  
將數字轉換為 DynamoDB 數字格式。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toNumber(12345)
Output:     { "N" : 12345 }
```

 **`util.dynamodb.toNumberSet(List<Number>)`**  
將數字清單轉換為 DynamoDB 數字集格式。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toNumberSet([ 1, 23, 4.56 ])
Output:     { "NS" : [ 1, 23, 4.56 ] }
```

## toBinary utils
<a name="utility-helpers-in-toBinary-js"></a>

### toBinary utils 清單
<a name="utility-helpers-in-toBinary-list-js"></a>

 **`util.dynamodb.toBinary(String)`**  
將編碼為 base64 字串的二進位資料轉換為 DynamoDB 二進位格式。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toBinary("foo")
Output:     { "B" : "foo" }
```

 **`util.dynamodb.toBinarySet(List<String>)`**  
將編碼為 base64 字串的二進位資料清單轉換為 DynamoDB 二進位集格式。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toBinarySet([ "foo", "bar", "baz" ])
Output:     { "BS" : [ "foo", "bar", "baz" ] }
```

## toBoolean utils
<a name="utility-helpers-in-toBoolean-js"></a>

### toBoolean utils 清單
<a name="utility-helpers-in-toBoolean-list-js"></a>

 **`util.dynamodb.toBoolean(Boolean)`**  
將布林值轉換為適當的 DynamoDB 布林值格式。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toBoolean(true)
Output:     { "BOOL" : true }
```

## toNull utils
<a name="utility-helpers-in-toNull-js"></a>

### toNull utils 清單
<a name="utility-helpers-in-toNull-list-js"></a>

 **`util.dynamodb.toNull()`**  
以 DynamoDB null 格式傳回 null。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toNull()
Output:     { "NULL" : null }
```

## toList utils
<a name="utility-helpers-in-toList-js"></a>

### toList utils 清單
<a name="utility-helpers-in-toList-list-js"></a>

**`util.dynamodb.toList(List)`**  
將物件清單轉換為 DynamoDB 清單格式。清單中的每個項目也會轉換為其適當的 DynamoDB 格式。它在代表一些巢狀物件的方式上是固定的：例如，它會使用清單 (「L」) 而不是集合 (「SS」、「NS」、「BS」)。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toList([ "foo", 123, { "bar" : "baz" } ])
Output:     {
               "L" : [
                   { "S" : "foo" },
                   { "N" : 123 },
                   {
                       "M" : {
                           "bar" : { "S" : "baz" }
                       }
                   }
               ]
           }
```

## toMap 公用程式
<a name="utility-helpers-in-toMap-js"></a>

### toMap 公用程式清單
<a name="utility-helpers-in-toMap-list-js"></a>

 **`util.dynamodb.toMap(Map)`**  
將映射轉換為 DynamoDB 映射格式。映射中的每個值也會轉換為其適當的 DynamoDB 格式。它在代表一些巢狀物件的方式上是固定的：例如，它會使用清單 (「L」) 而不是集合 (「SS」、「NS」、「BS」)。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toMap({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "M" : {
                   "foo"  : { "S" : "bar" },
                   "baz"  : { "N" : 1234 },
                   "beep" : {
                       "L" : [
                           { "S" : "boop" }
                       ]
                   }
               }
           }
```

 **`util.dynamodb.toMapValues(Map)`**  
建立映射的副本，其中每個值都已轉換為其適當的 DynamoDB 格式。它在代表一些巢狀物件的方式上是固定的：例如，它會使用清單 (「L」) 而不是集合 (「SS」、「NS」、「BS」)。  

```
Input:      util.dynamodb.toMapValues({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "foo"  : { "S" : "bar" },
               "baz"  : { "N" : 1234 },
               "beep" : {
                   "L" : [
                       { "S" : "boop" }
                   ]
               }
           }
```
這與 略有不同，`util.dynamodb.toMap(Map)`因為它只會傳回 DynamoDB 屬性值的內容，但不會傳回整個屬性值本身。例如，下列陳述式完全相同：  

```
util.dynamodb.toMapValues(<map>)
util.dynamodb.toMap(<map>)("M")
```

## S3Object 公用程式
<a name="utility-helpers-in-S3Object-js"></a>

### S3Object 公用程式清單
<a name="utility-helpers-in-S3Object-list-js"></a>

**`util.dynamodb.toS3Object(String key, String bucket, String region)`**  
將金鑰、儲存貯體和區域轉換為 DynamoDB S3 物件表示法。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toS3Object("foo", "bar", region = "baz")
Output:     { "S" : "{ \"s3\" : { \"key\" : \"foo", \"bucket\" : \"bar", \"region\" : \"baz" } }" }
```

**`util.dynamodb.toS3Object(String key, String bucket, String region, String version)`**  
將金鑰、儲存貯體、區域和選用版本轉換為 DynamoDB S3 物件表示法。這會傳回描述 DynamoDB 屬性值的物件。  

```
Input:      util.dynamodb.toS3Object("foo", "bar", "baz", "beep")
Output:     { "S" : "{ \"s3\" : { \"key\" : \"foo\", \"bucket\" : \"bar\", \"region\" : \"baz\", \"version\" = \"beep\" } }" }
```

 **`util.dynamodb.fromS3ObjectJson(String)`**  
接受 DynamoDB S3 物件的字串值，並傳回包含金鑰、儲存貯體、區域和選用版本的映射。  

```
Input:      util.dynamodb.fromS3ObjectJson({ "S" : "{ \"s3\" : { \"key\" : \"foo\", \"bucket\" : \"bar\", \"region\" : \"baz\", \"version\" = \"beep\" } }" })
Output:     { "key" : "foo", "bucket" : "bar", "region" : "baz", "version" : "beep" }
```

# util.http 中的 HTTP 協助程式
<a name="http-helpers-in-utils-http-js"></a>

`util.http` 公用程式提供協助程式方法，您可以用來管理 HTTP 請求參數和新增回應標頭。

## util.http utils 清單
<a name="http-helpers-in-utils-http-list-js"></a>

 **`util.http.copyHeaders(headers)`**  
從映射複製標頭，不包括下列受限 HTTP 標頭：  
+ transfer-encoding
+ connection
+ host
+ expect
+ keep-alive
+ upgrade
+ proxy-authenticate
+ proxy-authorization
+ te
+ content-length

**`util.http.addResponseHeader(String, Object)`**  
新增具有回應名稱 (`String`) 和值 (`Object`) 的單一自訂標頭。有下列限制：  
+ 除了 的限制標頭清單之外`copyHeaders(headers)`，標頭名稱也不符合下列任何項目：
  + Access-Control-Allow-Credentials
  + Access-Control-Allow-Origin
  + Access-Control-Expose-Headers
  + Access-Control-Max-Age
  + Access-Control-Allow-Methods
  + Access-Control-Allow-Headers
  + Vary
  + Content-Type
+ 標頭名稱不能以限制字首`x-amzn-`或 開頭`x-amz-`。
+ 自訂回應標頭的大小不能超過 4 KB。這包括標頭名稱和值。
+ 您應該為每個 GraphQL 操作定義每個回應標頭一次。不過，如果您多次定義同名的自訂標頭，最近的定義會出現在回應中。無論命名為何，所有標頭都會計入標頭大小限制。
+ 具有空白或限制名稱`(String)`或 null 值的標頭`(Object)`將被忽略，並產生新增到操作`errors`輸出的`ResponseHeaderError`錯誤。

```
export function request(ctx) {
  util.http.addResponseHeader('itemsCount', 7)
  util.http.addResponseHeader('render', ctx.args.render)
  return {}
}
```

**`util.http.addResponseHeaders(Map)`**  
將多個回應標頭新增至指定名稱`(String)`和值映射 的回應`(Object)`。為 `addResponseHeader(String, Object)`方法列出的相同限制也適用於此方法。  

```
export function request(ctx) {
  const headers = {
    headerInt: 12,
    headerString: 'stringValue',
    headerObject: {
      field1: 7,
      field2: 'string'
    }
  }
  util.http.addResponseHeaders(headers)
  return {}
}
```

# util.transform 中的轉換協助程式
<a name="transformation-helpers-in-utils-transform-js"></a>

`util.transform` 包含協助程式方法，可讓您更輕鬆地對資料來源執行複雜的操作。

## 轉換協助程式使用清單
<a name="transformation-helpers-in-utils-transform-js-list"></a>

**`util.transform.toDynamoDBFilterExpression(filterObject: DynamoDBFilterObject) : string`**  
將輸入字串轉換為篩選條件表達式，以搭配 DynamoDB 使用。我們建議您`toDynamoDBFilterExpression`搭配[內建模組函數](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-modules-js.html)使用 。

**`util.transform.toElasticsearchQueryDSL(object: OpenSearchQueryObject) : string`**  
將指定的輸入轉換為其同等的 OpenSearch Query DSL 表達式，將其傳回為 JSON 字串。  
**範例輸入：**  

```
util.transform.toElasticsearchQueryDSL({
    "upvotes":{
        "ne":15,
        "range":[
            10,
            20
        ]
    },
    "title":{
        "eq":"hihihi",
        "wildcard":"h*i"
    }
  })
```
**輸出範例：**  

```
{
    "bool":{
      "must":[
          {
            "bool":{
              "must":[
                  {
                    "bool":{
                      "must_not":{
                        "term":{
                          "upvotes":15
                        }
                      }
                    }
                  },
                  {
                    "range":{
                      "upvotes":{
                        "gte":10,
                        "lte":20
                      }
                    }
                  }
              ]
            }
          },
          {
            "bool":{
              "must":[
                  {
                    "term":{
                      "title":"hihihi"
                    }
                  },
                  {
                  "wildcard":{
                      "title":"h*i"
                    }
                  }
              ]
            }
          }
      ]
    }
}
```
預設運算子假設為 AND。

**`util.transform.toSubscriptionFilter(objFilter, ignoredFields?, rules?): SubscriptionFilter`**  
將`Map`輸入物件轉換為`SubscriptionFilter`表達式物件。`util.transform.toSubscriptionFilter` 方法會用作`extensions.setSubscriptionFilter()`延伸模組的輸入。如需詳細資訊，請參閱 [延伸模組](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)。  
參數和傳回陳述式如下所示：  
*參數*  
+ `objFilter`: `SubscriptionFilterObject`

  轉換為`SubscriptionFilter`表達式物件的`Map`輸入物件。
+ `ignoredFields`：`SubscriptionFilterExcludeKeysType`（選用）

  將忽略的第一個物件中欄位名稱`List`的 。
+ `rules`：`SubscriptionFilterRuleObject`（選用）

  當您建構`SubscriptionFilter`表達式物件時，包含嚴格規則的`Map`輸入物件。這些嚴格的規則將包含在`SubscriptionFilter`表達式物件中，以便至少滿足其中一個規則以傳遞訂閱篩選條件。
*回應*  
傳回 `[SubscriptionFilter](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)`。

**`util.transform.toSubscriptionFilter(Map, List)`**  
將`Map`輸入物件轉換為`SubscriptionFilter`表達式物件。`util.transform.toSubscriptionFilter` 方法會用作`extensions.setSubscriptionFilter()`延伸模組的輸入。如需詳細資訊，請參閱[延伸模組](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)。  
第一個引數是轉換為`SubscriptionFilter`表達式物件的`Map`輸入物件。第二個引數是欄位名稱`List`的 ，在建構`SubscriptionFilter`表達式物件時會在第一個`Map`輸入物件中忽略。

**`util.transform.toSubscriptionFilter(Map, List, Map)`**  
將`Map`輸入物件轉換為`SubscriptionFilter`表達式物件。`util.transform.toSubscriptionFilter` 方法會用作`extensions.setSubscriptionFilter()`延伸模組的輸入。如需詳細資訊，請參閱 [延伸模組](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)。

**`util.transform.toDynamoDBConditionExpression(conditionObject)`**  
建立 DynamoDB 條件表達式。

## 訂閱篩選條件引數
<a name="subscription-filter-arguments-js"></a>

下表說明如何定義下列公用程式的引數：
+ `Util.transform.toSubscriptionFilter(objFilter, ignoredFields?, rules?): SubscriptionFilter`

------
#### [ Argument 1: Map ]

引數 1 是具有下列索引鍵值的`Map`物件：
+ 欄位名稱
+ 「和」
+ "或"

對於做為索引鍵的欄位名稱，這些欄位項目的條件格式為 `"operator" : "value"`。

下列範例顯示如何將項目新增至 `Map`：

```
"field_name" : {
                    "operator1" : value             
               }

## We can have multiple conditions for the same field_name: 

"field_name" : {
                    "operator1" : value             
                    "operator2" : value
                    .
                    .
                    .                  
               }
```

當欄位上有兩個或多個條件時，所有這些條件都會被視為使用 OR 操作。

輸入`Map`也可以將「和」和「或」做為索引鍵，表示這些輸入中的所有項目都應該使用 AND 或 OR 邏輯聯結，視索引鍵而定。索引鍵值「和」和「或」預期有一系列條件。

```
"and" : [
            
            {
                "field_name1" : {
                    "operator1" : value             
                }
             },
             
             {
                "field_name2" : {
                    "operator1" : value             
                }
             },
             .
             .
        ].
```

請注意，您可以巢狀化「和」和「或」。也就是說，您可以在另一個「和」/」或」區塊中巢狀「和」/」或「或」。不過，這不適用於簡單欄位。

```
"and" : [
            
            {
                "field_name1" : {
                    "operator" : value             
                }
             },
             
             {
                "or" : [
                            {
                                "field_name2" : {
                                    "operator" : value             
                                }
                            },
                            
                            {
                                "field_name3" : {
                                    "operator" : value             
                                }
                            }
              
                        ].
```

下列範例顯示使用 *輸入引數 1*`util.transform.toSubscriptionFilter(Map) : Map`。

**Input(s)**

引數 1：映射：

```
{
  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "gt": 2000
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

**輸出**

結果是 `Map` 物件：

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "lte",
          "value": 50
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Admin"
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "lte",
          "value": 50
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "gte",
          "value": 20
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Admin"
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "gte",
          "value": 20
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    }
  ]
}
```

------
#### [ Argument 2: List ]

引數 2 包含建構`SubscriptionFilter`表達式物件時不應在輸入中考慮`List`的一組欄位名稱 `Map`（引數 1)。`List` 也可以是空的。

下列範例顯示使用 的引數 1 和引數 2 的輸入`util.transform.toSubscriptionFilter(Map, List) : Map`。

**Input(s)**

引數 1：映射：

```
{
  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "gt": 20
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

引數 2：列出：

```
["percentageUp", "author"]
```

**輸出**

結果是 `Map` 物件：

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    }
  ]
}
```

------
#### [ Argument 3: Map ]

引數 3 是具有欄位名稱作為索引鍵值的`Map`物件 （不能具有「和」或「或」)。對於做為索引鍵的欄位名稱，這些欄位的條件是 形式的項目`"operator" : "value"`。與引數 1 不同，引數 3 不能在同一個索引鍵中有多個條件。此外，引數 3 沒有「和」或「或」子句，因此也沒有涉及巢狀。

引數 3 代表新增至`SubscriptionFilter`表達式物件的嚴格規則清單，因此**至少符合其中一個**條件才能傳遞篩選條件。

```
{
  "fieldname1": {
    "operator": value
  },
  "fieldname2": {
    "operator": value
  }
}
.
.
.
```

下列範例顯示使用 的*引數 1*、*引數 2* 和*引數 3* 的輸入`util.transform.toSubscriptionFilter(Map, List, Map) : Map`。

**Input(s)**

引數 1：映射：

```
{
  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "lt": 20
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

引數 2：列出：

```
["percentageUp", "author"]
```

引數 3：映射：

```
{
  "upvotes": {
    "gte": 250
  },
  "author": {
    "eq": "Person1"
  }
}
```

**輸出**

結果是`Map`物件：

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        },
        {
          "fieldName": "upvotes",
          "operator": "gte",
          "value": 250
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Person1"
        }
      ]
    }
  ]
}
```

------

# util.str 中的字串協助程式
<a name="str-helpers-in-util-str-js"></a>

 `util.str` 包含有助於常見字串操作的方法。

## util.str utils 清單
<a name="str-helpers-in-util-str-list-js"></a>

 **`util.str.normalize(String, String)`**  
使用四個 Unicode 標準化形式之一來標準化字串：NFC、NFD、NFKC 或 NFKD。第一個引數是要標準化的字串。第二個引數是 "nfc"、"nfd"、"nfkc" 或 "nfkd"，指定用於標準化程序的標準化類型。

# 延伸模組
<a name="extensions-js"></a>

`extensions` 包含一組方法，可在解析程式中執行其他動作。

## 快取擴充功能
<a name="caching-extensions-js-list"></a>

**`extensions.evictFromApiCache(typeName: string, fieldName: string, keyValuePair: Record<string, any>) : Object`**  
從 AWS AppSync 伺服器端快取中移出項目。第一個引數是類型名稱。第二個引數是欄位名稱。第三個引數是包含金鑰值對項目的物件，可指定快取金鑰值。您必須在快取解析程式的 中，以與快取金鑰相同的順序放置物件中的項目`cachingKey`。如需快取的詳細資訊，請參閱[快取行為](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html#caching-behavior)。  
**範例 1：**  
此範例會移出針對已呼叫 的解析程式快取的項目`Query.allClasses`，而該解析程式`context.arguments.semester`會使用呼叫 的快取金鑰。當呼叫變動且解析程式執行時，如果項目已成功清除，則回應會在延伸項目物件中包含一個`apiCacheEntriesDeleted`值，顯示已刪除多少項目。  

```
import { util, extensions } from '@aws-appsync/utils';

export const request = (ctx) => ({ payload: null });

export function response(ctx) {
	extensions.evictFromApiCache('Query', 'allClasses', {
		'context.arguments.semester': ctx.args.semester,
	});
	return null;
}
```
此函數**僅適用於**變動，不適用於查詢。

## 訂閱擴充功能
<a name="subscription-extensions-js-list"></a>

**`extensions.setSubscriptionFilter(filterJsonObject)`**  
定義增強型訂閱篩選條件。每個訂閱通知事件都會根據提供的訂閱篩選條件進行評估，並在所有篩選條件評估為 時傳送通知給用戶端`true`。引數為 `filterJsonObject`（如需此引數的詳細資訊，請參閱以下*引數：filterJsonObject* 區段）。請參閱[增強型訂閱篩選](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html)。  
您只能在訂閱解析程式的回應處理常式中使用此延伸函數。此外，我們建議您使用 `util.transform.toSubscriptionFilter` 來建立篩選條件。

**`extensions.setSubscriptionInvalidationFilter(filterJsonObject)`**  
定義訂閱失效篩選條件。系統會針對失效承載評估訂閱篩選條件，如果篩選條件評估為 ，則會使指定的訂閱失效`true`。引數為 `filterJsonObject`（如需此引數的詳細資訊，請參閱以下*引數：filterJsonObject* 區段）。請參閱[增強型訂閱篩選](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html)。  
您只能在訂閱解析程式的回應處理常式中使用此延伸函數。此外，我們建議您使用 `util.transform.toSubscriptionFilter` 來建立篩選條件。

**`extensions.invalidateSubscriptions(invalidationJsonObject)`**  
用來從變動啟動訂閱失效。引數為 `invalidationJsonObject`（如需此引數的詳細資訊，請參閱以下*引數： invalidationJsonObject* 區段）。  
此延伸模組只能用於變動解析程式的回應映射範本。  
在任何單一請求中，您最多只能使用五個唯一的`extensions.invalidateSubscriptions()`方法呼叫。如果您超過此限制，您將會收到 GraphQL 錯誤。

## 引數：filterJsonObject
<a name="extensions-filterJsonObject-js"></a>

JSON 物件會定義訂閱或失效篩選條件。這是 中的一系列篩選條件`filterGroup`。每個篩選條件都是個別篩選條件的集合。

```
{
    "filterGroup": [
        {
           "filters" : [
                 {
                    "fieldName" : "userId",
                    "operator" : "eq",
                    "value" : 1
                }
           ]
           
        },
        {
           "filters" : [
                {
                    "fieldName" : "group",
                    "operator" : "in",
                    "value" : ["Admin", "Developer"]
                }
           ]
           
        }
    ]
}
```

每個篩選條件都有三個屬性：
+ `fieldName` – GraphQL 結構描述欄位。
+ `operator` – 運算子類型。
+ `value` – 要與訂閱通知值比較`fieldName`的值。

以下是這些屬性的範例指派：

```
{
 "fieldName" : "severity",
 "operator" : "le",
 "value" : context.result.severity
}
```

## 引數： invalidationJsonObject
<a name="extensions-invalidationJsonObject-js"></a>

`invalidationJsonObject` 定義下列項目：
+ `subscriptionField` – 要失效的 GraphQL 結構描述訂閱。定義為 中字串的單一訂閱`subscriptionField`會被視為失效。
+ `payload` – 金鑰/值對清單，當失效篩選條件`true`根據其值評估為 時，此清單會做為使訂閱失效的輸入。

  當訂閱解析程式中定義的失效篩選條件`true`針對 `payload`值評估為 時，下列範例會使用`onUserDelete`訂閱使已訂閱和已連線的用戶端失效。

  ```
  export const request = (ctx) => ({ payload: null });
  
  export function response(ctx) {
  	extensions.invalidateSubscriptions({
  		subscriptionField: 'onUserDelete',
  		payload: { group: 'Developer', type: 'Full-Time' },
  	});
  	return ctx.result;
  }
  ```

# util.xml 中的 XML 協助程式
<a name="xml-helpers-in-util-xml-js"></a>

 `util.xml` 包含有助於 XML 字串轉換的方法。

## util.xml utils 清單
<a name="xml-helpers-in-util-xml-list-js"></a>

 **`util.xml.toMap(String) : Object`**  
將 XML 字串轉換為字典。  
**範例 1：**  

```
Input:

<?xml version="1.0" encoding="UTF-8"?>
<posts>
<post>
    <id>1</id>
    <title>Getting started with GraphQL</title>
</post>
</posts>

Output (object):

{
    "posts":{
      "post":{
        "id":1,
        "title":"Getting started with GraphQL"
      }
    }
}
```
**範例 2：**  

```
Input:

<?xml version="1.0" encoding="UTF-8"?>
<posts>
<post>
  <id>1</id>
  <title>Getting started with GraphQL</title>
</post>
<post>
  <id>2</id>
  <title>Getting started with AppSync</title>
</post>
</posts>

Output (JavaScript object):

{
    "posts":{
    "post":[
        {
            "id":1,
            "title":"Getting started with GraphQL"
        },
        {
            "id":2,
            "title":"Getting started with AppSync"
        }
    ]
    }
}
```

**`util.xml.toJsonString(String, Boolean?) : String`**  
將 XML 字串轉換為 JSON 字串。這類似於 `toMap`，但輸出是字串。如果要將來自 HTTP 物件的 XML 回應直接轉換並傳回給 JSON，這非常實用。您可以設定選用的布林值參數，以判斷您是否要對 JSON 進行字串編碼。

# DynamoDB 的AWS AppSync JavaScript 解析程式函數參考
<a name="js-resolver-reference-dynamodb"></a>

The AWS AppSync DynamoDB 函數可讓您使用 [GraphQL](https://graphql.org)，將傳入的 GraphQL 請求映射至 DynamoDB DynamoDB 呼叫，然後將 DynamoDB 回應映射回 GraphQL，以在帳戶中現有的 Amazon DynamoDB 資料表中存放和擷取資料。本節說明受支援 DynamoDB 操作的請求和回應處理常式：
+  [GetItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-getitem.html) - GetItem 請求可讓您指示 DynamoDB 函數向 DynamoDB 提出 GetItem 請求，並可讓您在 DynamoDB 中指定項目的索引鍵，以及是否使用一致的讀取。
+  [ PutItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-putitem.html) - PutItem 請求映射文件可讓您指示 DynamoDB 函數向 DynamoDB 提出 PutItem 請求，並可讓您在 DynamoDB 中指定項目的金鑰、項目的完整內容 （由金鑰和attributeValues組成），以及操作成功的條件。
+  [ UpdateItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-updateitem.html) - UpdateItem 請求可讓您指示 DynamoDB 函數向 DynamoDB 提出 UpdateItem 請求，並允許您在 DynamoDB 中指定項目的索引鍵、描述如何在 DynamoDB 中更新項目的更新表達式，以及操作成功的條件。
+  [ DeleteItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-deleteitem.html) - DeleteItem 請求可讓您指示 DynamoDB 函數向 DynamoDB 提出 DeleteItem 請求，並可讓您在 DynamoDB 中指定項目的索引鍵，以及操作成功的條件。
+  [ 查詢 ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-query.html) - 查詢請求物件可讓您指示 DynamoDB 解析程式向 DynamoDB 提出查詢請求，並可讓您指定金鑰表達式、要使用的索引、額外的篩選條件、要傳回的項目數、是否使用一致的讀取、查詢方向 （向前或向後） 和分頁字符。
+  [ 掃描 ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-scan.html) - 掃描請求可讓您指示 DynamoDB 函數向 DynamoDB 發出掃描請求，並可讓您指定篩選條件以排除結果、要使用的索引、要傳回的項目數、是否使用一致的讀取、分頁字符和平行掃描。
+  [ Sync ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-sync.html) - Sync 請求物件可讓您從 DynamoDB 資料表擷取所有結果，然後只接收自上次查詢後更改的資料 （差異更新）。同步請求只能對版本控制的 DynamoDB 資料來源提出。您可以指定篩選條件來排除結果、要傳回的項目數、分頁權杖，以及上次同步操作啟動的時間。
+  [ BatchGetItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-batch-get-item.html) - BatchGetItem 請求物件可讓您指示 DynamoDB 函數向 DynamoDB 提出 BatchGetItem 請求，以擷取可能跨多個資料表的多個項目。對於此請求物件，您必須指定要從中擷取項目的資料表名稱，以及要從每個資料表中擷取之項目的索引鍵。
+  [ BatchDeleteItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-batch-delete-item.html) - BatchDeleteItem 請求物件可讓您指示 DynamoDB 函數向 DynamoDB 提出 BatchWriteItem 請求，以刪除可能跨多個資料表的多個項目。對於此請求物件，您必須指定要從中刪除項目的資料表名稱，以及要從每個資料表中刪除之項目的索引鍵。
+  [ BatchPutItem ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-batch-put-item.html) - BatchPutItem 請求物件可讓您指示 DynamoDB 函數向 DynamoDB 提出 BatchWriteItem 請求，以放置多個項目，可能跨越多個資料表。對於此請求物件，您必須指定要放入項目的資料表名稱，以及要放入每個資料表的完整項目。
+  [ TransactGetItems ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-transact-get-items.html) - TransactGetItems 請求物件可讓您指示 DynamoDB 函數向 DynamoDB 提出 TransactGetItems 請求，以擷取可能跨多個資料表的多個項目。對於此請求物件，您必須指定每個請求項目的資料表名稱，以便從中擷取項目，以及每個請求項目的索引鍵，以便從每個資料表中擷取。
+  [ TransactWriteItems ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-transact-write-items.html) - TransactWriteItems 請求物件可讓您指示 DynamoDB 函數向 DynamoDB 提出 TransactWriteItems 請求，以寫入多個項目，可能寫入多個資料表。對於此請求物件，您必須指定每個請求項目的目的地資料表名稱、要執行的每個請求項目的操作，以及要寫入的每個請求項目的索引鍵。
+  [ 類型系統 （請求映射） ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-typed-values-request.html) - 進一步了解 DynamoDB 類型如何整合到 AWS AppSync 請求中。
+  [ 類型系統 （回應映射） ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-typed-values-responses.html) - 進一步了解 DynamoDB 類型如何在回應承載中自動轉換為 GraphQL 或 JSON。
+  [篩選條件](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-filter.html) - 進一步了解查詢和掃描操作的篩選條件。
+  [ 條件表達式 ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-condition-expressions.html) - 進一步了解 PutItem、UpdateItem 和 DeleteItem 操作的條件表達式。
+  [ 交易條件表達式 ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions.html) - 進一步了解 TransactWriteItems 操作的條件表達式。
+  [ 投影 ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-projections.html) - 進一步了解如何在讀取操作中指定屬性。

# GetItem
<a name="js-aws-appsync-resolver-reference-dynamodb-getitem"></a>

`GetItem` 請求可讓您指示 AWS AppSync DynamoDB 函數向 DynamoDB 提出`GetItem`請求，並可讓您指定：
+ DynamoDB 中項目的索引鍵
+ 是否使用一致性讀取

`GetItem` 請求具有下列結構：

```
type DynamoDBGetItem = {
  operation: 'GetItem';
  key: { [key: string]: any };
  consistentRead?: ConsistentRead;
  projection?: {
    expression: string;
    expressionNames?: { [key: string]: string };
  };
};
```

欄位定義如下：

## GetItem 欄位
<a name="js-getitem-list"></a>

### GetItem 欄位清單
<a name="js-getitem-list-col"></a>

 **`operation`**   
要執行的 DynamoDB 操作。若要執行 `GetItem` DynamoDB 操作，這必須設為 `GetItem`。此值為必填。

 **`key`**   
DynamoDB 中項目的索引鍵。DynamoDB 項目可能具有單一雜湊索引鍵，或雜湊索引鍵和排序索引鍵，視資料表結構而定。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此值為必填。

 **`consistentRead`**   
是否使用 DynamoDB 執行強式一致讀取。此為選用，預設值為 `false`。

**`projection`**  
用於指定要從 DynamoDB 操作傳回之屬性的投影。如需投影的詳細資訊，請參閱[投影](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)。此欄位為選用欄位。

從 DynamoDB 傳回的項目會自動轉換為 GraphQL 和 JSON 基本類型，並且可在內容結果 () 中使用`context.result`。

如需 DynamoDB 類型轉換的詳細資訊，請參閱[類型系統 （回應映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

如需 JavaScript 解析程式的詳細資訊，請參閱 [JavaScript 解析程式概觀](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)。

## 範例
<a name="js-example"></a>

下列範例是 GraphQL 查詢 的函數請求處理常式`getThing(foo: String!, bar: String!)`：

```
export function request(ctx) {
  const {foo, bar} = ctx.args
  return {
    operation : "GetItem",
    key : util.dynamodb.toMapValues({foo, bar}),
    consistentRead : true
  }
}
```

如需 DynamoDB `GetItem` API 的詳細資訊，請參閱 [DynamoDB API 文件](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html)。

# PutItem
<a name="js-aws-appsync-resolver-reference-dynamodb-putitem"></a>

`PutItem` 請求映射文件可讓您指示 AWS AppSync DynamoDB 函數向 DynamoDB 提出`PutItem`請求，並可讓您指定下列項目：
+ DynamoDB 中項目的索引鍵
+ 項目 (由 `key` 和 `attributeValues` 組成) 的完整內容
+ 操作成功的條件

`PutItem` 請求具有下列結構：

```
type DynamoDBPutItemRequest = {
  operation: 'PutItem';
  key: { [key: string]: any };
  attributeValues: { [key: string]: any};
  condition?: ConditionCheckExpression;
  customPartitionKey?: string;
  populateIndexFields?: boolean;
  _version?: number;
};
```

欄位定義如下：

## PutItem 欄位
<a name="js-putitem-list"></a>

### PutItem 欄位清單
<a name="js-putitem-list-col"></a>

 **`operation`**   
要執行的 DynamoDB 操作。若要執行 `PutItem` DynamoDB 操作，這必須設為 `PutItem`。此值為必填。

 **`key`**   
DynamoDB 中項目的索引鍵。DynamoDB 項目可能具有單一雜湊索引鍵，或雜湊索引鍵和排序索引鍵，視資料表結構而定。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此值為必填。

 **`attributeValues`**   
將放入 DynamoDB 的項目其餘屬性。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此欄位為選用欄位。

 **`condition`**   
決定要求是否成功的條件，可根據已存在於 DynamoDB 的物件狀態。如果沒有指定條件，`PutItem` 要求會覆寫該項目的任何現有資料項目。如需條件的詳細資訊，請參閱[條件表達式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-condition-expressions)。此值是選用的。

 **`_version`**   
代表項目之最新已知版本的數值。此值是選用的。此欄位用於*衝突偵測*，而且僅支援已建立版本的資料來源。

**`customPartitionKey`**  
啟用時，此字串值會修改啟用版本控制時差異同步資料表所使用的 `ds_sk`和 `ds_pk` 記錄格式 （如需詳細資訊，請參閱 *AWS AppSync 開發人員指南*中的[衝突偵測和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html))。啟用時，也會啟用`populateIndexFields`項目的處理。此欄位為選用欄位。

**`populateIndexFields`**  
布林值，當 **與 啟用`customPartitionKey`**時，會為差異同步資料表中的每個記錄建立新的項目，特別是在 `gsi_ds_pk`和 `gsi_ds_sk`欄中。如需詳細資訊，請參閱 *AWS AppSync 開發人員指南*中的[衝突偵測和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)。此欄位為選用欄位。  
寫入 DynamoDB 的項目會自動轉換為 GraphQL 和 JSON 基本類型，並可在內容結果 () 中使用`context.result`。

寫入 DynamoDB 的項目會自動轉換為 GraphQL 和 JSON 基本類型，並可在內容結果 () 中使用`context.result`。

如需 DynamoDB 類型轉換的詳細資訊，請參閱[類型系統 （回應映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

如需 JavaScript 解析程式的詳細資訊，請參閱 [JavaScript 解析程式概觀](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)。

## 範例 1
<a name="js-example-1"></a>

下列範例是 GraphQL 變動 的函數請求處理常式`updateThing(foo: String!, bar: String!, name: String!, version: Int!)`。

若無指定索引鍵的項目，則會建立該項目。若已有指定索引鍵的項目，則會覆寫該項目。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, ...values} = ctx.args
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({foo, bar}),
    attributeValues: util.dynamodb.toMapValues(values),
  };
}
```

## 範例 2
<a name="js-example-2"></a>

下列範例是 GraphQL 變動 的函數請求處理常式`updateThing(foo: String!, bar: String!, name: String!, expectedVersion: Int!)`。

此範例會驗證目前在 DynamoDB 中的項目已將 `version` 欄位設定為 `expectedVersion`。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, name, expectedVersion } = ctx.args;
  const values = { name, version: expectedVersion + 1 };
  let condition = util.transform.toDynamoDBConditionExpression({
    version: { eq: expectedVersion },
  });

  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ foo, bar }),
    attributeValues: util.dynamodb.toMapValues(values),
    condition,
  };
}
```

如需 DynamoDB `PutItem` API 的詳細資訊，請參閱 [DynamoDB API 文件](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)。

# UpdateItem
<a name="js-aws-appsync-resolver-reference-dynamodb-updateitem"></a>

`UpdateItem` 請求可讓您指示 AWS AppSync DynamoDB 函數向 DynamoDB 提出`UpdateItem`請求，並可讓您指定下列項目：
+ DynamoDB 中項目的索引鍵
+ 描述如何在 DynamoDB 中更新項目的更新表達式
+ 操作成功的條件

`UpdateItem` 請求具有下列結構：

```
type DynamoDBUpdateItemRequest = {
  operation: 'UpdateItem';
  key: { [key: string]: any };
  update: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  condition?: ConditionCheckExpression;
  customPartitionKey?: string;
  populateIndexFields?: boolean;
  _version?: number;
};
```

欄位定義如下：

## UpdateItem 欄位
<a name="js-updateitem-list"></a>

### UpdateItem 欄位清單
<a name="js-updateitem-list-col"></a>

 **`operation`**   
要執行的 DynamoDB 操作。若要執行 `UpdateItem` DynamoDB 操作，這必須設為 `UpdateItem`。此值為必填。

 **`key`**   
DynamoDB 中項目的索引鍵。DynamoDB 項目可能具有單一雜湊索引鍵，或雜湊索引鍵和排序索引鍵，視資料表結構而定。如需指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此值為必填。

 **`update`**   
`update` 本節可讓您指定更新表達式，描述如何在 DynamoDB 中更新項目。如需有關如何撰寫更新表達式的詳細資訊，請參閱 [DynamoDB UpdateExpressions 文件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html)。此區段是必須的。  
`update` 區段有三個元件：    
** `expression` **  
更新表達式。此值為必填。  
** `expressionNames` **  
表達式屬性 *name* 預留位置的替代，形式為鍵值組。金鑰對應至 中使用的名稱預留位置`expression`，且值必須是對應於 DynamoDB 中項目屬性名稱的字串。此欄位為選用的，應只能填入用於 `expression` 中表達式屬性名稱預留位置的替代。  
** `expressionValues` **  
表達式屬性 *value* 預留位置的替代，形式為鍵值組。鍵對應用於 `expression` 的值預留位置，值必須是類型值。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此必須指定。此欄位為選用的，應只能填入用於 `expression` 中表達式屬性值預留位置的替代。

 **`condition`**   
決定要求是否成功的條件，可根據已存在於 DynamoDB 的物件狀態。如果沒有指定條件，`UpdateItem` 要求會更新現有的資料項目，無論項目的目前狀態為何。如需條件的詳細資訊，請參閱[條件表達式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-condition-expressions)。此值是選用的。

 **`_version`**   
代表項目之最新已知版本的數值。此值是選用的。此欄位用於*衝突偵測*，而且僅支援已建立版本的資料來源。

**`customPartitionKey`**  
啟用時，此字串值會修改啟用版本控制時差異同步資料表所使用的 `ds_sk`和 `ds_pk` 記錄格式 （如需詳細資訊，請參閱 *AWS AppSync 開發人員指南*中的[衝突偵測和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html))。啟用時，也會啟用`populateIndexFields`項目的處理。此欄位為選用欄位。

**`populateIndexFields`**  
布林值，當 **與 啟用`customPartitionKey`**時，會為差異同步資料表中的每個記錄建立新的項目，特別是在 `gsi_ds_pk`和 `gsi_ds_sk`欄中。如需詳細資訊，請參閱 *AWS AppSync 開發人員指南*中的[衝突偵測和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)。此欄位為選用欄位。

DynamoDB 中更新的項目會自動轉換為 GraphQL 和 JSON 基本類型，並可在內容結果 () 中使用`context.result`。

如需 DynamoDB 類型轉換的詳細資訊，請參閱[類型系統 （回應映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

如需 JavaScript 解析程式的詳細資訊，請參閱 [JavaScript 解析程式概觀](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)。

## 範例 1
<a name="js-id3"></a>

下列範例是 GraphQL 變動 的函數請求處理常式`upvote(id: ID!)`。

在此範例中，DynamoDB 中的項目的 `upvotes`和 `version` 欄位增量為 1。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { id } = ctx.args;
  return {
    operation: 'UpdateItem',
    key: util.dynamodb.toMapValues({ id }),
    update: {
      expression: 'ADD #votefield :plusOne, version :plusOne',
      expressionNames: { '#votefield': 'upvotes' },
      expressionValues: { ':plusOne': { N: 1 } },
    },
  };
}
```

## 範例 2
<a name="js-id4"></a>

下列範例是 GraphQL 變動 的函數請求處理常式`updateItem(id: ID!, title: String, author: String, expectedVersion: Int!)`。

這個複雜的範例會檢查引數，並持續產生更新表達式，其只包含由用戶端提供的引數。例如，如果 `title` 和 `author` 遭到省略，則不會更新。如果指定 引數，但其值為 `null`，則該欄位會從 DynamoDB 中的物件中刪除。最後， 操作有一個條件，可驗證目前在 DynamoDB 中的項目是否將 `version` 欄位設定為 `expectedVersion`：

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { args: { input: { id, ...values } } } = ctx;

  const condition = {
    id: { attributeExists: true },
    version: { eq: values.expectedVersion },
  };
  values.expectedVersion += 1;
  return dynamodbUpdateRequest({ keys: { id }, values, condition });
}


/**
 * Helper function to update an item
 * @returns an UpdateItem request
 */
function dynamodbUpdateRequest(params) {
  const { keys, values, condition: inCondObj } = params;

  const sets = [];
  const removes = [];
  const expressionNames = {};
  const expValues = {};

  // Iterate through the keys of the values
  for (const [key, value] of Object.entries(values)) {
    expressionNames[`#${key}`] = key;
    if (value) {
      sets.push(`#${key} = :${key}`);
      expValues[`:${key}`] = value;
    } else {
      removes.push(`#${key}`);
    }
  }

  let expression = sets.length ? `SET ${sets.join(', ')}` : '';
  expression += removes.length ? ` REMOVE ${removes.join(', ')}` : '';

  const condition = JSON.parse(
    util.transform.toDynamoDBConditionExpression(inCondObj)
  );

  return {
    operation: 'UpdateItem',
    key: util.dynamodb.toMapValues(keys),
    condition,
    update: {
      expression,
      expressionNames,
      expressionValues: util.dynamodb.toMapValues(expValues),
    },
  };
}
```

如需 DynamoDB `UpdateItem` API 的詳細資訊，請參閱 [DynamoDB API 文件](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html)。

# DeleteItem
<a name="js-aws-appsync-resolver-reference-dynamodb-deleteitem"></a>

`DeleteItem` 請求可讓您指示 AWS AppSync DynamoDB 函數向 DynamoDB 提出`DeleteItem`請求，並可讓您指定下列項目：
+ DynamoDB 中項目的索引鍵
+ 操作成功的條件

`DeleteItem` 請求具有下列結構：

```
type DynamoDBDeleteItemRequest = {
  operation: 'DeleteItem';
  key: { [key: string]: any };
  condition?: ConditionCheckExpression;
  customPartitionKey?: string;
  populateIndexFields?: boolean;
  _version?: number;
};
```

欄位定義如下：

## DeleteItem 欄位
<a name="js-deleteitem-list"></a>

### DeleteItem 欄位清單
<a name="js-deleteitem-list-col"></a>

** `operation` **  
要執行的 DynamoDB 操作。若要執行 `DeleteItem` DynamoDB 操作，這必須設為 `DeleteItem`。此值為必填。

** `key` **  
DynamoDB 中項目的索引鍵。DynamoDB 項目可能有單一雜湊索引鍵，或雜湊索引鍵和排序索引鍵，視資料表結構而定。如需指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此值為必填。

** `condition` **  
決定要求是否成功的條件，可根據已存在於 DynamoDB 的物件狀態。如果沒有指定條件，`DeleteItem` 要求會刪除項目，無論該項目的目前狀態為何。如需條件的詳細資訊，請參閱[條件表達式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-condition-expressions)。此值是選用的。

** `_version` **  
代表項目之最新已知版本的數值。此值是選用的。此欄位用於*衝突偵測*，而且僅支援已建立版本的資料來源。

**`customPartitionKey`**  
啟用時，此字串值會修改啟用版本控制時差異同步資料表所使用的 `ds_sk`和 `ds_pk` 記錄格式 （如需詳細資訊，請參閱 *AWS AppSync 開發人員指南*中的[衝突偵測和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html))。啟用時，也會啟用`populateIndexFields`項目的處理。此欄位為選用欄位。

**`populateIndexFields`**  
布林值，當 **與 啟用`customPartitionKey`**時，會為差異同步資料表中的每個記錄建立新的項目，特別是在 `gsi_ds_pk`和 `gsi_ds_sk`欄中。如需詳細資訊，請參閱 *AWS AppSync 開發人員指南*中的[衝突偵測和同步](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)。此欄位為選用欄位。

從 DynamoDB 刪除的項目會自動轉換為 GraphQL 和 JSON 基本類型，並可在內容結果 () 中使用`context.result`。

如需 DynamoDB 類型轉換的詳細資訊，請參閱[類型系統 （回應映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

如需 JavaScript 解析程式的詳細資訊，請參閱 [JavaScript 解析程式概觀](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)。

## 範例 1
<a name="js-id6"></a>

下列範例是 GraphQL 變動 的函數請求處理常式`deleteItem(id: ID!)`。如果已存在此 ID 的項目，則該項目將會遭到刪除。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'DeleteItem',
    key: util.dynamodb.toMapValues({ id: ctx.args.id }),
  };
}
```

## 範例 2
<a name="js-id7"></a>

下列範例是 GraphQL 變動 的函數請求處理常式`deleteItem(id: ID!, expectedVersion: Int!)`。如果已存在此 ID 的項目，則該項目將會遭到刪除，但其 `version` 欄位必須已設為 `expectedVersion`：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { id, expectedVersion } = ctx.args;
  const condition = {
    id: { attributeExists: true },
    version: { eq: expectedVersion },
  };
  return {
    operation: 'DeleteItem',
    key: util.dynamodb.toMapValues({ id }),
    condition: util.transform.toDynamoDBConditionExpression(condition),
  };
}
```

如需 DynamoDB `DeleteItem` API 的詳細資訊，請參閱 [DynamoDB API 文件](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html)。

# Query
<a name="js-aws-appsync-resolver-reference-dynamodb-query"></a>

`Query` 請求物件可讓您指示 AWS AppSync DynamoDB 解析程式向 DynamoDB 提出`Query`請求，並可讓您指定下列項目：
+ 索引鍵表達式
+ 要使用哪些索引
+ 任何額外篩選條件
+ 要傳回多少項目
+ 是否使用一致性讀取
+ 查詢方向 (向前或向後)
+ 分頁字符

`Query` 請求物件具有下列結構：

```
type DynamoDBQueryRequest = {
  operation: 'Query';
  query: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  index?: string;
  nextToken?: string;
  limit?: number;
  scanIndexForward?: boolean;
  consistentRead?: boolean;
  select?: 'ALL_ATTRIBUTES' | 'ALL_PROJECTED_ATTRIBUTES' | 'SPECIFIC_ATTRIBUTES';
  filter?: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  projection?: {
    expression: string;
    expressionNames?: { [key: string]: string };
  };
};
```

欄位定義如下：

## 查詢欄位
<a name="js-query-list"></a>

### 查詢欄位清單
<a name="js-query-list-col"></a>

** `operation` **  
要執行的 DynamoDB 操作。若要執行 `Query` DynamoDB 操作，這必須設為 `Query`。此值為必填。

** `query` **  
`query` 本節可讓您指定金鑰條件表達式，描述要從 DynamoDB 擷取哪些項目。如需如何編寫索引鍵條件表達式的詳細資訊，請參閱 [DynamoDB KeyConditions 文件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.KeyConditions.html)。必須指定此區段。    
** `expression` **  
查詢表達式。必須指定此欄位。  
** `expressionNames` **  
表達式屬性 *name* 預留位置的替代，形式為鍵值組。金鑰對應至 中使用的名稱預留位置`expression`，且值必須是對應於 DynamoDB 中項目屬性名稱的字串。此欄位為選用的，應只能填入用於 `expression` 中表達式屬性名稱預留位置的替代。  
** `expressionValues` **  
表達式屬性 *value* 預留位置的替代，形式為鍵值組。鍵對應用於 `expression` 的值預留位置，值必須是類型值。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此值為必填。此欄位為選用的，應只能填入用於 `expression` 中表達式屬性值預留位置的替代。

** `filter` **  
額外的篩選條件可用來在傳回 DynamoDB 的結果之前先篩選結果。如需篩選條件的詳細資訊，請參閱[篩選條件](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-filter)。此欄位為選用欄位。

** `index` **  
要查詢的索引名稱。除了雜湊索引鍵的主索引鍵之外，DynamoDB 查詢操作還可讓您掃描本機次要索引和全域次要索引。如果指定，這會通知 DynamoDB 查詢指定的索引。若省略，則會查詢主索引鍵索引。

** `nextToken` **  
分頁字符將繼續先前的查詢。這會是從先前查詢所取得的。此欄位為選用欄位。

** `limit` **  
要評估的項目數上限 (不一定是相符的項目數)。此欄位為選用欄位。

** `scanIndexForward` **  
指出是否向前或向後查詢的布林值。此欄位為選用，預設值為 `true`。

** `consistentRead` **  
布林值，指出在查詢 DynamoDB 時是否使用一致讀取。此欄位為選用，預設值為 `false`。

** `select` **  
根據預設， AWS AppSync DynamoDB 解析程式只會傳回投影到索引中的屬性。如果需要更多屬性，請設定這個欄位。此欄位為選用欄位。支援的值是：    
** `ALL_ATTRIBUTES` **  
傳回所有指定資料表或索引的項目屬性。如果您查詢本機次要索引，DynamoDB 會從索引中每個相符項目的父資料表擷取整個項目。如果索引設定為投射所有項目屬性，所有資料都可從本機次要索引取得，不需進行任何擷取。  
** `ALL_PROJECTED_ATTRIBUTES` **  
只在查詢索引時才允許。擷取所有已投射到索引的屬性。如果索引設定為投射所有屬性，此傳回值相當於指定 `ALL_ATTRIBUTES`。  
**`SPECIFIC_ATTRIBUTES`**  
僅傳回 中列出的屬性`projection``expression`。此傳回值等同於指定 `projection`的 ，`expression`而不指定 的任何值`Select`。

**`projection`**  
用於指定要從 DynamoDB 操作傳回之屬性的投影。如需投影的詳細資訊，請參閱[投影](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)。此欄位為選用欄位。

DynamoDB 的結果會自動轉換為 GraphQL 和 JSON 基本類型，並可在內容結果 () 中使用`context.result`。

如需 DynamoDB 類型轉換的詳細資訊，請參閱[類型系統 （回應映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

如需 JavaScript 解析程式的詳細資訊，請參閱 [JavaScript 解析程式概觀](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)。

結果的結構如下：

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10
}
```

欄位定義如下：

** `items` **  
包含 DynamoDB 查詢傳回項目的清單。

** `nextToken` **  
如果可能有一個以上的結果，`nextToken` 會包含可用於另一個要求的分頁字符。請注意， AWS AppSync 會加密和混淆從 DynamoDB 傳回的分頁字符。這樣可確保資料表的資料不會不慎洩漏給發起人。另請注意，這些分頁字符不能用於不同的函數或解析程式。

** `scannedCount` **  
套用篩選條件表達式 (若有的話) 以前符合查詢條件表達式的項目數。

## 範例
<a name="js-id9"></a>

下列範例是 GraphQL 查詢 的函數請求處理常式`getPosts(owner: ID!)`。

在此範例中，資料表上的全域次要索引受到查詢，以傳回指定 ID 擁有的所有文章。

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { owner } = ctx.args;
  return {
    operation: 'Query',
    query: {
      expression: 'ownerId = :ownerId',
      expressionValues: util.dynamodb.toMapValues({ ':ownerId': owner }),
    },
    index: 'owner-index',
  };
}
```

如需 DynamoDB `Query` API 的詳細資訊，請參閱 [DynamoDB API 文件](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html)。

# Scan
<a name="js-aws-appsync-resolver-reference-dynamodb-scan"></a>

`Scan` 請求可讓您指示 AWS AppSync DynamoDB 函數向 DynamoDB 提出`Scan`請求，並可讓您指定下列項目：
+ 排除結果的篩選結果
+ 要使用哪些索引
+ 要傳回多少項目
+ 是否使用一致性讀取
+ 分頁字符
+ 平行掃描

`Scan` 請求物件具有下列結構：

```
type DynamoDBScanRequest = {
  operation: 'Scan';
  index?: string;
  limit?: number;
  consistentRead?: boolean;
  nextToken?: string;
  totalSegments?: number;
  segment?: number;
  filter?: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  projection?: {
    expression: string;
    expressionNames?: { [key: string]: string };
  };
};
```

欄位定義如下：

## 掃描欄位
<a name="js-scan-list"></a>

### 掃描欄位清單
<a name="js-scan-list-col"></a>

** `operation` **  
要執行的 DynamoDB 操作。若要執行 `Scan` DynamoDB 操作，這必須設為 `Scan`。此值為必填。

** `filter` **  
在傳回 DynamoDB 的結果之前，可用來篩選結果的篩選條件。如需篩選條件的詳細資訊，請參閱[篩選條件](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-filter)。此欄位為選用欄位。

** `index` **  
要查詢的索引名稱。除了雜湊索引鍵的主索引鍵之外，DynamoDB 查詢操作還可讓您掃描本機次要索引和全域次要索引。如果指定，這會通知 DynamoDB 查詢指定的索引。若省略，則會查詢主索引鍵索引。

** `limit` **  
單次可評估的項目數量上限。此欄位為選用欄位。

** `consistentRead` **  
布林值，指出在查詢 DynamoDB 時是否使用一致讀取。此欄位為選用，預設值為 `false`。

** `nextToken` **  
分頁字符將繼續先前的查詢。這會是從先前查詢所取得的。此欄位為選用欄位。

** `select` **  
根據預設， AWS AppSync DynamoDB 函數只會傳回投影到索引中的任何屬性。如果需要更多屬性，則此欄位可以設定。此欄位為選用欄位。支援的值是：    
** `ALL_ATTRIBUTES` **  
傳回所有指定資料表或索引的項目屬性。如果您查詢本機次要索引，DynamoDB 會從索引中每個相符項目的父資料表擷取整個項目。如果索引設定為投射所有項目屬性，所有資料都可從本機次要索引取得，不需進行任何擷取。  
** `ALL_PROJECTED_ATTRIBUTES` **  
只在查詢索引時才允許。擷取所有已投射到索引的屬性。如果索引設定為投射所有屬性，此傳回值相當於指定 `ALL_ATTRIBUTES`。  
**`SPECIFIC_ATTRIBUTES`**  
僅傳回 中列出的屬性`projection``expression`。此傳回值等同於指定 `projection`的 ，`expression`而不指定 的任何值`Select`。

** `totalSegments` **  
執行平行掃描時分割資料表的區段數。此欄位為選用的，但若指定 `segment`，則此欄位必須指定。

** `segment` **  
此操作中執行平行掃描時的資料表區段。此欄位為選用的，但若指定 `totalSegments`，則此欄位必須指定。

**`projection`**  
用於指定要從 DynamoDB 操作傳回之屬性的投影。如需投影的詳細資訊，請參閱[投影](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)。此欄位為選用欄位。

DynamoDB 掃描傳回的結果會自動轉換為 GraphQL 和 JSON 基本類型，並可在內容結果 () 中使用`context.result`。

如需 DynamoDB 類型轉換的詳細資訊，請參閱[類型系統 （回應映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

如需 JavaScript 解析程式的詳細資訊，請參閱 [JavaScript 解析程式概觀](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)。

結果的結構如下：

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10
}
```

欄位定義如下：

** `items` **  
包含 DynamoDB 掃描傳回項目的清單。

** `nextToken` **  
如果結果可能更多， `nextToken` 包含一個分頁字符，您可以在另一個請求中使用。 AWS AppSync 會加密和混淆從 DynamoDB 傳回的分頁字符。這樣可確保資料表的資料不會不慎洩漏給發起人。此外，這些分頁字符無法用於不同的函數或解析程式。

** `scannedCount` **  
在套用篩選條件表達式 （如果有） 之前，DynamoDB 擷取的項目數量。

## 範例 1
<a name="js-id11"></a>

下列範例是 GraphQL 查詢的函數請求處理常式：`allPosts`。

在此範例中，資料表中的所有項目都會傳回。

```
export function request(ctx) {
  return { operation: 'Scan' };
}
```

## 範例 2
<a name="js-id12"></a>

下列範例是 GraphQL 查詢的函數請求處理常式：`postsMatching(title: String!)`。

在此範例中，資料表中開頭為 `title` 引數的所有項目都會傳回。

```
export function request(ctx) {
  const { title } = ctx.args;
  const filter = { filter: { beginsWith: title } };
  return {
    operation: 'Scan',
    filter: JSON.parse(util.transform.toDynamoDBFilterExpression(filter)),
  };
}
```

如需 DynamoDB `Scan` API 的詳細資訊，請參閱 [DynamoDB API 文件](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html)。

# Sync
<a name="js-aws-appsync-resolver-reference-dynamodb-sync"></a>

`Sync` 請求物件可讓您從 DynamoDB 資料表擷取所有結果，然後只接收自上次查詢後變更的資料 （差異更新）。 `Sync` 請求只能對版本控制的 DynamoDB 資料來源提出。您可以指定下列項目：
+ 排除結果的篩選結果
+ 要傳回多少項目
+ 分頁字符
+ 上次起始 `Sync` 操作時

`Sync` 請求物件具有下列結構：

```
type DynamoDBSyncRequest = {
  operation: 'Sync';
  basePartitionKey?: string;
  deltaIndexName?: string;
  limit?: number;
  nextToken?: string;
  lastSync?: number;
  filter?: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
};
```

欄位定義如下：

## 同步欄位
<a name="js-sync-list"></a>

### 同步欄位清單
<a name="js-sync-list-col"></a>

** `operation` **  
要執行的 DynamoDB 操作。若要執行 `Sync` 操作，這必須設定為 `Sync`。此值為必填。

** `filter` **  
在傳回 DynamoDB 的結果之前，可用來篩選結果的篩選條件。如需篩選條件的詳細資訊，請參閱[篩選條件](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-filter)。此欄位為選用欄位。

** `limit` **  
單次可評估的項目數量上限。此欄位為選用欄位。如果省略此值，預設限制將設為 `100` 個項目。此欄位的最大值為 `1000` 個項目。

** `nextToken` **  
分頁字符將繼續先前的查詢。這會是從先前查詢所取得的。此欄位為選用欄位。

** `lastSync` **  
上次成功啟動 `Sync` 操作的時間 (以毫秒為單位)。如果指定此值，只會傳回 `lastSync` 之後變更的項目。這個欄位是選用的，而且只有在初始 `Sync` 操作擷取所有頁面之後才能填入。如果省略此值，將傳回 *Base* 資料表的結果，否則會傳回 *Delta* 資料表的結果。

**`basePartitionKey`**  
執行`Sync`操作時使用之 *Base* 資料表的分割區索引鍵。此欄位允許在資料表使用自訂分割區索引鍵時執行`Sync`操作。此為選用欄位。

**`deltaIndexName`**  
用於 `Sync`操作的索引。當資料表使用自訂分割區索引鍵時，需要此索引才能在整個差異存放區資料表上啟用`Sync`操作。`Sync` 操作將在 GSI 上執行 （在 `gsi_ds_pk`和 上建立`gsi_ds_sk`)。此欄位為選用欄位。

DynamoDB 同步傳回的結果會自動轉換為 GraphQL 和 JSON 基本類型，並可在內容結果 () 中使用`context.result`。

如需 DynamoDB 類型轉換的詳細資訊，請參閱[類型系統 （回應映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)。

如需 JavaScript 解析程式的詳細資訊，請參閱 [JavaScript 解析程式概觀](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)。

結果的結構如下：

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10,
    startedAt = 1550000000000
}
```

欄位定義如下：

** `items` **  
包含同步傳回項目的清單。

** `nextToken` **  
如果結果可能更多， `nextToken` 包含一個分頁字符，您可以在另一個請求中使用。 AWS AppSync 會加密和混淆從 DynamoDB 傳回的分頁字符。這樣可確保資料表的資料不會不慎洩漏給發起人。此外，這些分頁字符無法用於不同的函數或解析程式。

** `scannedCount` **  
在套用篩選條件表達式 （如果有） 之前，DynamoDB 擷取的項目數量。

** `startedAt` **  
開始同步操作時，可以在本機存放並在另一個請求中做為 `lastSync` 引數的時間 (以 epoch 毫秒為單位)。如果請求中包含分頁字符，則該值將與請求針對第一頁結果傳回的值相同。

## 範例
<a name="js-id14"></a>

下列範例是 GraphQL 查詢的函數請求處理常式：`syncPosts(nextToken: String, lastSync: AWSTimestamp)`。

在此範例中，如果省略 `lastSync`，則會傳回 Base 資料表中的所有項目。如果提供 `lastSync`，只會傳回自 `lastSync` 變更之 Delta Sync 資料表中的項目。

```
export function request(ctx) {
  const { nextToken, lastSync } = ctx.args;
  return { operation: 'Sync', limit: 100, nextToken, lastSync };
}
```

# BatchGetItem
<a name="js-aws-appsync-resolver-reference-dynamodb-batch-get-item"></a>

`BatchGetItem` 請求物件可讓您指示 AWS AppSync DynamoDB 函數向 DynamoDB 提出`BatchGetItem`請求，以擷取可能跨多個資料表的多個項目。對於此請求物件，您必須指定下列項目：
+ 將從其中擷取項目的資料表名稱
+ 將從個別資料表擷取項目的索引鍵

此時會套用 DynamoDB `BatchGetItem` 限制，且可能不會提供**任何條件表達式**。

`BatchGetItem` 請求物件具有下列結構：

```
type DynamoDBBatchGetItemRequest = {
  operation: 'BatchGetItem';
  tables: {
    [tableName: string]: {
      keys: { [key: string]: any }[];
      consistentRead?: boolean; 
      projection?: {
        expression: string;
        expressionNames?: { [key: string]: string };
      };
    };
  };
};
```

欄位定義如下：

## BatchGetItem 欄位
<a name="js-BatchGetItem-list"></a>

### BatchGetItem 欄位清單
<a name="js-BatchGetItem-list-col"></a>

** `operation` **  
要執行的 DynamoDB 操作。若要執行 `BatchGetItem` DynamoDB 操作，這必須設為 `BatchGetItem`。此值為必填。

** `tables` **  
要從中擷取項目的 DynamoDB 資料表。此值是其中將資料表名稱指定為該映射索引鍵的映射。至少必須提供一個資料表。`tables` 值為必填。    
** `keys` **  
代表要擷取之項目主索引鍵的 DynamoDB 索引鍵清單。DynamoDB 項目可能有單一雜湊索引鍵，或雜湊索引鍵和排序索引鍵，視資料表結構而定。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。  
** `consistentRead` **  
執行 *GetItem* 操作時是否使用一致性讀取。此值為選用值，且預設值為 *false*。  
**`projection`**  
用於指定要從 DynamoDB 操作傳回之屬性的投影。如需投影的詳細資訊，請參閱[投影](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)。此欄位為選用欄位。

注意事項：
+ 如果未從資料表中擷取任何項目，該資料表的 data 區塊中會顯示 *null* 元素。
+ 調用結果會根據在請求物件內提供的順序，依資料表排序。
+ 中的每個`Get`命令`BatchGetItem`都是原子的，但批次可以部分處理。如果因錯誤而部分批次處理，則未處理的索引鍵會透過 *unprocessedKeys* 區塊傳回為部分的呼叫結果。
+  `BatchGetItem` 限制為 100 個索引鍵。

對於下列範例函數請求處理常式：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { authorId, postId } = ctx.args;
  return {
    operation: 'BatchGetItem',
    tables: {
      authors: [util.dynamodb.toMapValues({ authorId })],
      posts: [util.dynamodb.toMapValues({ authorId, postId })],
    },
  };
}
```

可透過 `ctx.result` 提供的呼叫結果如下所示：

```
{
   "data": {
     "authors": [null],
     "posts": [
        // Was retrieved
        {
          "authorId": "a1",
          "postId": "p2",
          "postTitle": "title",
          "postDescription": "description",
        }
     ]
   },
   "unprocessedKeys": {
     "authors": [
        // This item was not processed due to an error
        {
          "authorId": "a1"
        }
      ],
     "posts": []
   }
}
```

`ctx.error` 包含錯誤的詳細資訊。金鑰**資料**、**unprocessedKeys** 和在函數請求物件結果中提供的每個資料表金鑰，保證會出現在調用結果中。已刪除的項目會出現在 **data** 區塊中。尚未處理的項目在該 data 區塊中會標示為 *null*，並置於 **unprocessedKeys** 區塊。

# BatchDeleteItem
<a name="js-aws-appsync-resolver-reference-dynamodb-batch-delete-item"></a>

`BatchDeleteItem` 請求物件可讓您指示 AWS AppSync DynamoDB 函數向 DynamoDB 提出`BatchWriteItem`請求，以刪除可能跨多個資料表的多個項目。對於此請求物件，您必須指定下列項目：
+ 將從其中刪除項目的資料表名稱
+ 將從個別資料表刪除項目的索引鍵

此時會套用 DynamoDB `BatchWriteItem` 限制，且可能不會提供**任何條件表達式**。

`BatchDeleteItem` 請求物件具有下列結構：

```
type DynamoDBBatchDeleteItemRequest = {
  operation: 'BatchDeleteItem';
  tables: {
    [tableName: string]: { [key: string]: any }[];
  };
};
```

欄位定義如下：

## BatchDeleteItem 欄位
<a name="js-BatchDeleteItem-list"></a>

### BatchDeleteItem 欄位清單
<a name="js-BatchDeleteItem-list-col"></a>

** `operation` **  
要執行的 DynamoDB 操作。若要執行 `BatchDeleteItem` DynamoDB 操作，這必須設為 `BatchDeleteItem`。此值為必填。

** `tables` **  
要從中刪除項目的 DynamoDB 資料表。每個資料表都是代表要刪除項目之主索引鍵的 DynamoDB 索引鍵清單。DynamoDB 項目可能具有單一雜湊索引鍵，或雜湊索引鍵和排序索引鍵，視資料表結構而定。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。至少必須提供一個資料表。`tables` 值為必要。

注意事項：
+ 不同於 `DeleteItem` 操作，回應中未傳回完整刪除的項目。只會傳回已傳遞的索引鍵。
+ 如果資料表中未刪除任何項目，該資料表的 data 區塊中就會顯示 *null* 元素。
+ 調用結果會根據在請求物件內提供的順序，依資料表排序。
+ 中的每個`Delete`命令`BatchDeleteItem`都是原子的。但是，批次可以部分處理。如果因錯誤而部分批次處理，則未處理的索引鍵會透過 *unprocessedKeys* 區塊傳回為部分的呼叫結果。
+  `BatchDeleteItem` 限制為 25 個索引鍵。
+ 與衝突偵測搭配使用時，**不支援**此操作。同時使用兩者可能會導致錯誤。

對於下列範例函數請求處理常式：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { authorId, postId } = ctx.args;
  return {
    operation: 'BatchDeleteItem',
    tables: {
      authors: [util.dynamodb.toMapValues({ authorId })],
      posts: [util.dynamodb.toMapValues({ authorId, postId })],
    },
  };
}
```

可透過 `ctx.result` 提供的呼叫結果如下所示：

```
{
   "data": {
     "authors": [null],
     "posts": [
        // Was deleted
        {
          "authorId": "a1",
          "postId": "p2"
        }
     ]
   },
   "unprocessedKeys": {
     "authors": [
        // This key was not processed due to an error
        {
          "authorId": "a1"
        }
      ],
     "posts": []
   }
}
```

`ctx.error` 包含錯誤的詳細資訊。函數請求物件中提供的索引鍵**資料**、**unprocessedKeys** 和每個資料表索引鍵保證會出現在調用結果中。已刪除的項目會出現在 **data** 區塊中。尚未處理的項目在該 data 區塊中會標示為 *null*，並置於 **unprocessedKeys** 區塊。

# BatchPutItem
<a name="js-aws-appsync-resolver-reference-dynamodb-batch-put-item"></a>

`BatchPutItem` 請求物件可讓您指示 AWS AppSync DynamoDB 函數向 DynamoDB 提出`BatchWriteItem`請求，以放置多個項目，可能跨越多個資料表。對於此請求物件，您必須指定下列項目：
+ 項目將放入其中的資料表名稱
+ 將放入每個資料表的所有項目

此時會套用 DynamoDB `BatchWriteItem` 限制，且可能不會提供**任何條件表達式**。

`BatchPutItem` 請求物件具有下列結構：

```
type DynamoDBBatchPutItemRequest = {
  operation: 'BatchPutItem';
  tables: {
    [tableName: string]: { [key: string]: any}[];
  };
};
```

欄位定義如下：

## BatchPutItem 欄位
<a name="js-BatchPutItem-list"></a>

### BatchPutItem 欄位清單
<a name="js-BatchPutItem-list-col"></a>

** `operation` **  
要執行的 DynamoDB 操作。若要執行 `BatchPutItem` DynamoDB 操作，這必須設為 `BatchPutItem`。此值為必填。

** `tables` **  
要放入項目的 DynamoDB 資料表。每個資料表項目代表要為此特定資料表插入的 DynamoDB 項目清單。至少必須提供一個資料表。此值為必填。

注意事項：
+ 若插入成功，回應會傳回完全插入的項目。
+ 如果資料表中並未插入任何項目，該資料表的 data 區塊中就會顯示 *null* 元素。
+ 插入的項目會根據在請求物件內提供的順序，依資料表排序。
+ 不過， 內的每個`Put`命令`BatchPutItem`都是原子的，但可以部分處理批次。如果因錯誤而部分批次處理，則未處理的索引鍵會透過 *unprocessedKeys* 區塊傳回為部分的呼叫結果。
+  `BatchPutItem` 限制為 25 個項目。
+ 與衝突偵測搭配使用時，**不支援**此操作。同時使用兩者可能會導致錯誤。

對於下列範例函數請求處理常式：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { authorId, postId, name, title } = ctx.args;
  return {
    operation: 'BatchPutItem',
    tables: {
      authors: [util.dynamodb.toMapValues({ authorId, name })],
      posts: [util.dynamodb.toMapValues({ authorId, postId, title })],
    },
  };
}
```

可透過 `ctx.result` 提供的呼叫結果如下所示：

```
{
   "data": {
     "authors": [
         null
     ],
     "posts": [
        // Was inserted
        {
          "authorId": "a1",
          "postId": "p2",
          "title": "title"
        }
     ]
   },
   "unprocessedItems": {
     "authors": [
        // This item was not processed due to an error
        {
          "authorId": "a1",
          "name": "a1_name"
        }
      ],
     "posts": []
   }
}
```

`ctx.error` 包含錯誤的詳細資訊。請求物件中提供的金鑰**資料**、**unprocessedItems** 和每個資料表金鑰都保證會出現在調用結果中。已插入的項目會出現在 **data** 區塊中。尚未處理的項目在該 data 區塊中會標示為 *null*，並置於 **unprocessedItems** 區塊。

# TransactGetItems
<a name="js-aws-appsync-resolver-reference-dynamodb-transact-get-items"></a>

`TransactGetItems` 請求物件可讓您指示 AWS AppSync DynamoDB 函數向 DynamoDB 提出`TransactGetItems`請求，以擷取可能跨多個資料表的多個項目。對於此請求物件，您必須指定下列項目：
+ 從中擷取項目之每個請求項目的資料表名稱
+ 從每個資料表擷取之每個請求項目的索引鍵

此時會套用 DynamoDB `TransactGetItems` 限制，且可能不會提供**任何條件表達式**。

`TransactGetItems` 請求物件具有下列結構：

```
type DynamoDBTransactGetItemsRequest = {
  operation: 'TransactGetItems';
  transactItems: { table: string; key: { [key: string]: any }; projection?: { expression: string; expressionNames?: { [key: string]: string }; }[];
  };
};
```

欄位定義如下：

## TransactGetItems 欄位
<a name="js-TransactGetItems-list"></a>

### TransactGetItems 欄位清單
<a name="js-TransactGetItems-list-col"></a>

** `operation` **  
要執行的 DynamoDB 操作。若要執行 `TransactGetItems` DynamoDB 操作，這必須設為 `TransactGetItems`。此值為必填。

** `transactItems` **  
要包含的請求項目。此值是請求項目的陣列。必須提供至少一個請求項目。`transactItems` 值為必填。    
** `table` **  
要從中擷取項目的 DynamoDB 資料表。此值是資料表名稱的字串。`table` 值為必填。  
** `key` **  
代表要擷取之項目主索引鍵的 DynamoDB 索引鍵。DynamoDB 項目可能具有單一雜湊索引鍵，或雜湊索引鍵和排序索引鍵，視資料表結構而定。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。  
**`projection`**  
用於指定要從 DynamoDB 操作傳回之屬性的投影。如需投影的詳細資訊，請參閱[投影](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)。此欄位為選用欄位。

注意事項：
+ 如果交易成功，`items` 區塊中擷取項目的順序會與請求項目的順序相同。
+ 以全有或全無的方式執行交易。如果任何請求項目造成錯誤，將不執行整個交易，而且將傳回錯誤詳細資料。
+ 無法擷取的請求項目不是錯誤。相反地，*null* 元素會出現在對應位置的*項目*區塊。
+ 如果交易錯誤是 *TransactionCanceledException*，則會填入 `cancellationReasons` 區塊。`cancellationReasons` 區塊中取消原因的順序將與請求項目的順序相同。
+  `TransactGetItems` 限制為 100 個請求項目。

對於下列範例函數請求處理常式：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { authorId, postId } = ctx.args;
  return {
    operation: 'TransactGetItems',
    transactItems: [
      {
        table: 'posts',
        key: util.dynamodb.toMapValues({ postId }),
      },
      {
        table: 'authors',
        key: util.dynamodb.toMapValues({ authorId }),
      },
    ],
  };
}
```

如果交易成功，而且僅擷取第一個請求項目，則 `ctx.result` 中的可用叫用結果如下所示：

```
{
    "items": [
       {
           // Attributes of the first requested item
           "post_id": "p1",
           "post_title": "title",
           "post_description": "description"
       },
       // Could not retrieve the second requested item
       null,
    ],
    "cancellationReasons": null
}
```

如果因為第一個請求項目造成的 *TransactionCanceledException* 造成交易失敗，則 `ctx.result` 中的可用叫用結果如下所示：

```
{
    "items": null,
    "cancellationReasons": [
       {
           "type":"Sample error type",
           "message":"Sample error message"
       },
       {
           "type":"None",
           "message":"None"
       }
    ]
}
```

`ctx.error` 包含錯誤的詳細資訊。索引鍵 **items** 和 **cancellationReasons** 保證出現在 `ctx.result` 中。

# TransactWriteItems
<a name="js-aws-appsync-resolver-reference-dynamodb-transact-write-items"></a>

`TransactWriteItems` 請求物件可讓您指示 AWS AppSync DynamoDB 函數向 DynamoDB 提出`TransactWriteItems`請求，以寫入多個項目，可能寫入多個資料表。對於此請求物件，您必須指定下列項目：
+ 每個請求項目的目標資料表名稱
+ 每個請求項目要執行的操作。有四種支援的操作類型：*PutItem*、*UpdateItem*、*DeleteItem* 以及 *ConditionCheck* 
+ 每個要寫入之請求項目的索引鍵

套用 DynamoDB `TransactWriteItems` 限制。

`TransactWriteItems` 請求物件具有下列結構：

```
type DynamoDBTransactWriteItemsRequest = {
  operation: 'TransactWriteItems';
  transactItems: TransactItem[];
};
type TransactItem =
  | TransactWritePutItem
  | TransactWriteUpdateItem
  | TransactWriteDeleteItem
  | TransactWriteConditionCheckItem;
type TransactWritePutItem = {
  table: string;
  operation: 'PutItem';
  key: { [key: string]: any };
  attributeValues: { [key: string]: string};
  condition?: TransactConditionCheckExpression;
};
type TransactWriteUpdateItem = {
  table: string;
  operation: 'UpdateItem';
  key: { [key: string]: any };
  update: DynamoDBExpression;
  condition?: TransactConditionCheckExpression;
};
type TransactWriteDeleteItem = {
  table: string;
  operation: 'DeleteItem';
  key: { [key: string]: any };
  condition?: TransactConditionCheckExpression;
};
type TransactWriteConditionCheckItem = {
  table: string;
  operation: 'ConditionCheck';
  key: { [key: string]: any };
  condition?: TransactConditionCheckExpression;
};
type TransactConditionCheckExpression = {
  expression: string;
  expressionNames?: { [key: string]: string};
  expressionValues?: { [key: string]: any};
  returnValuesOnConditionCheckFailure: boolean;
};
```

## TransactWriteItems 欄位
<a name="js-TransactWriteItems-list"></a>

### TransactWriteItems 欄位清單
<a name="js-TransactWriteItems-list-col"></a>

**欄位定義如下：**    
** `operation` **  
要執行的 DynamoDB 操作。若要執行 `TransactWriteItems` DynamoDB 操作，這必須設為 `TransactWriteItems`。此值為必填。  
** `transactItems` **  
要包含的請求項目。此值是請求項目的陣列。必須提供至少一個請求項目。`transactItems` 值為必填。  
對於 `PutItem`，欄位定義如下：    
** `table` **  
目的地 DynamoDB 資料表。此值是資料表名稱的字串。`table` 值為必填。  
** `operation` **  
要執行的 DynamoDB 操作。若要執行 `PutItem` DynamoDB 操作，這必須設為 `PutItem`。此值為必填。  
** `key` **  
代表要放置之項目主索引鍵的 DynamoDB 索引鍵。DynamoDB 項目可能具有單一雜湊索引鍵，或雜湊索引鍵和排序索引鍵，視資料表結構而定。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此值為必填。  
** `attributeValues` **  
將放入 DynamoDB 的項目其餘屬性。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此欄位為選用欄位。  
** `condition` **  
決定要求是否成功的條件，可根據已存在於 DynamoDB 的物件狀態。如果沒有指定條件，`PutItem` 要求會覆寫該項目的任何現有資料項目。您可以指定在條件檢查失敗時是否擷取現有項目。如需交易條件的詳細資訊，請參閱[交易條件表達式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)。此值是選用的。
對於 `UpdateItem`，欄位定義如下：    
** `table` **  
要更新的 DynamoDB 資料表。此值是資料表名稱的字串。`table` 值為必填。  
** `operation` **  
要執行的 DynamoDB 操作。若要執行 `UpdateItem` DynamoDB 操作，這必須設為 `UpdateItem`。此值為必填。  
** `key` **  
代表要更新之項目主索引鍵的 DynamoDB 索引鍵。DynamoDB 項目可能具有單一雜湊索引鍵，或雜湊索引鍵和排序索引鍵，視資料表結構而定。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此值為必填。  
** `update` **  
`update` 本節可讓您指定更新表達式，描述如何在 DynamoDB 中更新項目。如需有關如何撰寫更新表達式的詳細資訊，請參閱 [DynamoDB UpdateExpressions 文件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html)。此區段是必須的。  
** `condition` **  
決定要求是否成功的條件，可根據已存在於 DynamoDB 的物件狀態。如果沒有指定條件，`UpdateItem` 要求會更新現有的資料項目，無論項目的目前狀態為何。您可以指定在條件檢查失敗時是否擷取現有項目。如需交易條件的詳細資訊，請參閱[交易條件表達式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)。此值是選用的。
對於 `DeleteItem`，欄位定義如下：    
** `table` **  
要在其中刪除項目的 DynamoDB 資料表。此值是資料表名稱的字串。`table` 值為必填。  
** `operation` **  
要執行的 DynamoDB 操作。若要執行 `DeleteItem` DynamoDB 操作，這必須設為 `DeleteItem`。此值為必填。  
** `key` **  
代表要刪除之項目主索引鍵的 DynamoDB 索引鍵。DynamoDB 項目可能具有單一雜湊索引鍵，或雜湊索引鍵和排序索引鍵，視資料表結構而定。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此值為必填。  
** `condition` **  
決定要求是否成功的條件，可根據已存在於 DynamoDB 的物件狀態。如果沒有指定條件，`DeleteItem` 要求會刪除項目，無論該項目的目前狀態為何。您可以指定在條件檢查失敗時是否擷取現有項目。如需交易條件的詳細資訊，請參閱[交易條件表達式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)。此值是選用的。
對於 `ConditionCheck`，欄位定義如下：    
** `table` **  
要檢查條件的 DynamoDB 資料表。此值是資料表名稱的字串。`table` 值為必填。  
** `operation` **  
要執行的 DynamoDB 操作。若要執行 `ConditionCheck` DynamoDB 操作，這必須設為 `ConditionCheck`。此值為必填。  
** `key` **  
代表要條件檢查之項目主索引鍵的 DynamoDB 索引鍵。DynamoDB 項目可能具有單一雜湊索引鍵，或雜湊索引鍵和排序索引鍵，視資料表結構而定。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此值為必填。  
** `condition` **  
決定要求是否成功的條件，可根據已存在於 DynamoDB 的物件狀態。您可以指定在條件檢查失敗時是否擷取現有項目。如需交易條件的詳細資訊，請參閱[交易條件表達式](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)。此值為必填。

注意事項：
+ 如果成功，只會在回應中傳回請求項目的索引鍵。索引鍵的順序將與請求項目的順序相同。
+ 以全有或全無的方式執行交易。如果任何請求項目造成錯誤，將不執行整個交易，而且將傳回錯誤詳細資料。
+ 沒有兩個請求項目可以定位到相同項目。否則，它們將造成 *TransactionCanceledException* 錯誤。
+ 如果交易錯誤是 *TransactionCanceledException*，則會填入 `cancellationReasons` 區塊。如果請求項目的條件檢查失敗，**而且**您未將 `returnValuesOnConditionCheckFailure` 指定為 `false`，將擷取資料表中存在的項目，並存放在 `cancellationReasons` 區塊之對應位置的 `item` 中。
+  `TransactWriteItems` 限制為 100 個請求項目。
+ 與衝突偵測搭配使用時，**不支援**此操作。同時使用兩者可能會導致錯誤。

對於下列範例函數請求處理常式：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { authorId, postId, title, description, oldTitle, authorName } = ctx.args;
  return {
    operation: 'TransactWriteItems',
    transactItems: [
      {
        table: 'posts',
        operation: 'PutItem',
        key: util.dynamodb.toMapValues({ postId }),
        attributeValues: util.dynamodb.toMapValues({ title, description }),
        condition: util.transform.toDynamoDBConditionExpression({
          title: { eq: oldTitle },
        }),
      },
      {
        table: 'authors',
        operation: 'UpdateItem',
        key: util.dynamodb.toMapValues({ authorId }),
        update: {
          expression: 'SET authorName = :name',
          expressionValues: util.dynamodb.toMapValues({ ':name': authorName }),
        },
      },
    ],
  };
}
```

如果交易成功，`ctx.result` 中可用的叫用結果如下所示：

```
{
    "keys": [
       // Key of the PutItem request
       {
           "post_id": "p1",
       },
       // Key of the UpdateItem request
       {
           "author_id": "a1"
       }
    ],
    "cancellationReasons": null
}
```

如果交易因為`PutItem`請求的條件檢查失敗而失敗， 中可用的調用結果`ctx.result`如下：

```
{
    "keys": null,
    "cancellationReasons": [
       {
           "item": {
               "post_id": "p1",
               "post_title": "Actual old title",
               "post_description": "Old description"
           },
           "type": "ConditionCheckFailed",
           "message": "The condition check failed."
       },
       {
           "type": "None",
           "message": "None"
       }
    ]
}
```

`ctx.error` 包含錯誤的詳細資訊。索引鍵 **keys** 和 **cancellationReasons** 保證出現在 `ctx.result` 中。

# 類型系統 （請求映射）
<a name="js-aws-appsync-resolver-reference-dynamodb-typed-values-request"></a>

使用 AWS AppSync DynamoDB 函數呼叫 DynamoDB 資料表時， AWS AppSync 需要知道要在該呼叫中使用的每個值類型。這是因為 DynamoDB 支援比 GraphQL 或 JSON 更多的類型基本概念 （例如集合和二進位資料）。 AWS AppSync 需要一些提示，否則您必須對資料表中的資料結構做出一些假設。 GraphQL DynamoDB

如需 DynamoDB 資料類型的詳細資訊，請參閱 DynamoDB [資料類型描述項](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html#Programming.LowLevelAPI.DataTypeDescriptors)和[資料類型](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes)文件。

DynamoDB 值由包含單一鍵值對的 JSON 物件表示。金鑰會指定 DynamoDB 類型，而值會指定值本身。在下列範例中，`S` 鍵代表值是字串，`identifier` 值則是字串值本身。

```
{ "S" : "identifier" }
```

請注意，JSON 物件不能有一個以上的索引值對。如果指定多個鍵/值對，則不會剖析請求物件。

DynamoDB 值會在您需要指定值的請求物件中的任何位置使用。您需要執行這項操作的一些地方包括：`key` 和 `attributeValue` 區段，以及表達式區段的 `expressionValues` 區段。在下列範例中，DynamoDB 字串值`identifier`會指派給`key`區段中的 `id` 欄位 （可能在`GetItem`請求物件中）。

```
"key" : {
   "id" : { "S" : "identifier" }
}
```

 **支援的類型** 

AWS AppSync 支援下列 DynamoDB 純量、文件和設定類型：

**字串類型 `S` **  
單一字串值。DynamoDB 字串值以下列表示：  

```
{ "S" : "some string" }
```
使用範例：  

```
"key" : {
   "id" : { "S" : "some string" }
}
```

**字串集類型 `SS` **  
字串值的集合。DynamoDB 字串集值以下列表示：  

```
{ "SS" : [ "first value", "second value", ... ] }
```
使用範例：  

```
"attributeValues" : {
   "phoneNumbers" : { "SS" : [ "+1 555 123 4567", "+1 555 234 5678" ] }
}
```

**數字類型 `N` **  
單一數值。DynamoDB 數字值以下列表示：  

```
{ "N" : 1234 }
```
使用範例：  

```
"expressionValues" : {
   ":expectedVersion" : { "N" : 1 }
}
```

**數字集類型 `NS` **  
數值的集合。DynamoDB 數字集值以下列表示：  

```
{ "NS" : [ 1, 2.3, 4 ... ] }
```
使用範例：  

```
"attributeValues" : {
   "sensorReadings" : { "NS" : [ 67.8, 12.2, 70 ] }
}
```

**二進位類型 `B` **  
二進位值。DynamoDB 二進位值以下列表示：  

```
{ "B" : "SGVsbG8sIFdvcmxkIQo=" }
```
請注意，該值實際上是字串，其中字串是二進位資料的 base64 編碼表示法。 AWS AppSync 會將此字串解碼回其二進位值，然後再傳送到 DynamoDB。 AWS AppSync 使用 RFC 2045 定義的 base64 解碼機制：忽略不在 base64 字母中的任何字元。  
使用範例：  

```
"attributeValues" : {
   "binaryMessage" : { "B" : "SGVsbG8sIFdvcmxkIQo=" }
}
```

**二進位集類型 `BS` **  
二進位值的集合。DynamoDB 二進位集值以下列表示：  

```
{ "BS" : [ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ... ] }
```
請注意，該值實際上是字串，其中字串是二進位資料的 base64 編碼表示法。 AWS AppSync 會將此字串解碼回其二進位值，然後再傳送至 DynamoDB。 AWS AppSync 使用 RFC 2045 定義的 base64 解碼機制：忽略不在 base64 字母中的任何字元。  
使用範例：  

```
"attributeValues" : {
   "binaryMessages" : { "BS" : [ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ] }
}
```

**布林類型 `BOOL` **  
布林值。DynamoDB 布林值以下列表示：  

```
{ "BOOL" : true }
```
請注意，只有 `true` 和 `false` 為有效值。  
使用範例：  

```
"attributeValues" : {
   "orderComplete" : { "BOOL" : false }
}
```

**清單類型 `L` **  
任何其他支援的 DynamoDB 值清單。DynamoDB 清單值以下列表示：  

```
{ "L" : [ ... ] }
```
請注意，該值是複合值，其中清單可包含任何支援的 DynamoDB 值的零或多個 （包括其他清單）。清單也可包含混合的不同類型。  
使用範例：  

```
{ "L" : [
      { "S"  : "A string value" },
      { "N"  : 1 },
      { "SS" : [ "Another string value", "Even more string values!" ] }
   ]
}
```

**映射類型 `M` **  
代表其他支援 DynamoDB 值的金鑰值對的未排序集合。DynamoDB Map 值以下列表示：  

```
{ "M" : { ... } }
```
請注意，映射可包含零或多個索引值對。金鑰必須是字串，且值可以是任何支援的 DynamoDB 值 （包括其他映射）。映射也可包含混合的不同類型。  
使用範例：  

```
{ "M" : {
      "someString" : { "S"  : "A string value" },
      "someNumber" : { "N"  : 1 },
      "stringSet"  : { "SS" : [ "Another string value", "Even more string values!" ] }
   }
}
```

**Null 類型 `NULL` **  
null 值。DynamoDB Null 值以下列表示：  

```
{ "NULL" : null }
```
使用範例：  

```
"attributeValues" : {
   "phoneNumbers" : { "NULL" : null }
}
```

如需每種類型的詳細資訊，請參閱 [DynamoDB 文件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html)。

# 類型系統 （回應映射）
<a name="js-aws-appsync-resolver-reference-dynamodb-typed-values-responses"></a>

從 DynamoDB 接收回應時， AWS AppSync 會自動將其轉換為 GraphQL 和 JSON 基本類型。DynamoDB 中的每個屬性都會解碼，並在回應處理常式的內容中傳回。

例如，如果 DynamoDB 傳回下列項目：

```
{
    "id" : { "S" : "1234" },
    "name" : { "S" : "Nadia" },
    "age" : { "N" : 25 }
}
```

從管道解析程式傳回結果時， AWS AppSync 會將結果轉換為 GraphQL 和 JSON 類型，如下所示：

```
{
    "id" : "1234",
    "name" : "Nadia",
    "age" : 25
}
```

本節說明 AWS AppSync 如何轉換下列 DynamoDB 純量、文件和設定類型：

**字串類型 `S` **  
單一字串值。DynamoDB 字串值會以字串傳回。  
例如，如果 DynamoDB 傳回下列 DynamoDB 字串值：  

```
{ "S" : "some string" }
```
AWS AppSync 將其轉換為字串：  

```
"some string"
```

**字串集類型 `SS` **  
字串值的集合。DynamoDB 字串集值會傳回為字串清單。  
例如，如果 DynamoDB 傳回下列 DynamoDB 字串集值：  

```
{ "SS" : [ "first value", "second value", ... ] }
```
AWS AppSync 將其轉換為字串清單：  

```
[ "+1 555 123 4567", "+1 555 234 5678" ]
```

**數字類型 `N` **  
單一數值。DynamoDB 數值會以數字傳回。  
例如，如果 DynamoDB 傳回下列 DynamoDB 數字值：  

```
{ "N" : 1234 }
```
AWS AppSync 將其轉換為數字：  

```
1234
```

**數字集類型 `NS` **  
數值的集合。DynamoDB 數字集值會以數字清單傳回。  
例如，如果 DynamoDB 傳回下列 DynamoDB 數字集值：  

```
{ "NS" : [ 67.8, 12.2, 70 ] }
```
AWS AppSync 將其轉換為數字清單：  

```
[ 67.8, 12.2, 70 ]
```

**二進位類型 `B` **  
二進位值。DynamoDB 二進位值會以字串傳回，其中包含該值的 base64 表示法。  
例如，如果 DynamoDB 傳回下列 DynamoDB 二進位值：  

```
{ "B" : "SGVsbG8sIFdvcmxkIQo=" }
```
AWS AppSync 將其轉換為包含 base64 表示值的字串：  

```
"SGVsbG8sIFdvcmxkIQo="
```
請注意，二進位資料以 base64 編碼配置編碼，如 [RFC 4648](https://tools.ietf.org/html/rfc4648) 和 [RFC 2045](https://tools.ietf.org/html/rfc2045) 中所定義。

**二進位集類型 `BS` **  
二進位值的集合。DynamoDB 二進位集值會以包含 base64 表示值的字串清單傳回。  
例如，如果 DynamoDB 傳回下列 DynamoDB 二進位集值：  

```
{ "BS" : [ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ... ] }
```
AWS AppSync 將其轉換為包含 base64 表示值的字串清單：  

```
[ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ... ]
```
請注意，二進位資料以 base64 編碼配置編碼，如 [RFC 4648](https://tools.ietf.org/html/rfc4648) 和 [RFC 2045](https://tools.ietf.org/html/rfc2045) 中所定義。

**布林類型 `BOOL` **  
布林值。DynamoDB 布林值會以布林值傳回。  
例如，如果 DynamoDB 傳回下列 DynamoDB 布林值：  

```
{ "BOOL" : true }
```
AWS AppSync 將其轉換為布林值：  

```
true
```

**清單類型 `L` **  
任何其他支援的 DynamoDB 值清單。DynamoDB 清單值會傳回為值清單，其中每個內部值也會轉換。  
例如，如果 DynamoDB 傳回下列 DynamoDB 清單值：  

```
{ "L" : [
      { "S"  : "A string value" },
      { "N"  : 1 },
      { "SS" : [ "Another string value", "Even more string values!" ] }
   ]
}
```
AWS AppSync 將其轉換為轉換值的清單：  

```
[ "A string value", 1, [ "Another string value", "Even more string values!" ] ]
```

**映射類型 `M` **  
任何其他支援的 DynamoDB 值的金鑰/值集合。DynamoDB Map 值會以 JSON 物件傳回，其中每個索引鍵/值也會轉換。  
例如，如果 DynamoDB 傳回下列 DynamoDB Map 值：  

```
{ "M" : {
      "someString" : { "S"  : "A string value" },
      "someNumber" : { "N"  : 1 },
      "stringSet"  : { "SS" : [ "Another string value", "Even more string values!" ] }
   }
}
```
AWS AppSync 將其轉換為 JSON 物件：  

```
{
   "someString" : "A string value",
   "someNumber" : 1,
   "stringSet"  : [ "Another string value", "Even more string values!" ]
}
```

**Null 類型 `NULL` **  
null 值。  
例如，如果 DynamoDB 傳回下列 DynamoDB Null 值：  

```
{ "NULL" : null }
```
AWS AppSync 將其轉換為 null：  

```
null
```

# 篩選條件
<a name="js-aws-appsync-resolver-reference-dynamodb-filter"></a>

使用 `Query`和 `Scan`操作查詢 DynamoDB 中的物件時，您可以選擇指定`filter`評估結果並僅傳回所需值的 。

`Query` 或 `Scan`請求的篩選條件屬性具有下列結構：

```
type DynamoDBExpression = {
  expression: string;
  expressionNames?: { [key: string]: string};
  expressionValues?: { [key: string]: any};
};
```

欄位定義如下：

** `expression` **  
查詢表達式。如需如何編寫篩選條件表達式的詳細資訊，請參閱 [DynamoDB QueryFilter](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.QueryFilter.html) 和 [DynamoDB ScanFilter](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.ScanFilter.html) 文件。必須指定此欄位。

** `expressionNames` **  
表達式屬性 *name* 預留位置的替代，形式為鍵值組。索引鍵對應至用於 `expression` 的名稱預留位置。值必須是對應於 DynamoDB 中項目屬性名稱的字串。此欄位為選用的，應只能填入用於 `expression` 中表達式屬性名稱預留位置的替代。

** `expressionValues` **  
表達式屬性 *value* 預留位置的替代，形式為鍵值組。鍵對應用於 `expression` 的值預留位置，值必須是類型值。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此必須指定。此欄位為選用的，應只能填入用於 `expression` 中表達式屬性值預留位置的替代。

## 範例
<a name="js-id18"></a>

下列範例是請求的篩選條件區段，只有在標題以 `title` 引數開頭時，才會傳回從 DynamoDB 擷取的項目。

在這裡，我們使用 從 物件`util.transform.toDynamoDBFilterExpression`自動建立篩選條件：

```
const filter = util.transform.toDynamoDBFilterExpression({
  title: { beginsWith: 'far away' },
});

const request = {};
request.filter = JSON.parse(filter);
```

這會產生下列篩選條件：

```
{
  "filter": {
    "expression": "(begins_with(#title,:title_beginsWith))",
    "expressionNames": { "#title": "title" },
    "expressionValues": {
      ":title_beginsWith": { "S": "far away" }
    }
  }
}
```

# 條件表達式
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-expressions"></a>

當您使用 `PutItem`、 `UpdateItem`和 DynamoDB 操作來變更 `DeleteItem` DynamoDB 中的物件時，您可以選擇指定條件表達式，以根據在執行操作之前已在 DynamoDB 中的物件狀態來控制請求是否成功。

The AWS AppSync DynamoDB 函數允許在 `PutItem`、 `UpdateItem`和 `DeleteItem`請求物件中指定條件表達式，以及如果條件失敗且未更新物件時要遵循的策略。

## 範例 1
<a name="js-id19"></a>

下列`PutItem`請求物件沒有條件表達式。因此，即使具有相同索引鍵的項目已存在，也會將項目放入 DynamoDB，藉此覆寫現有項目。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, ...values} = ctx.args
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({foo, bar}),
    attributeValues: util.dynamodb.toMapValues(values),
  };
}
```

## 範例 2
<a name="js-id20"></a>

下列`PutItem`物件有條件表達式，只有在 DynamoDB 中*不存在*具有相同索引鍵的項目時，才允許操作成功。

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, ...values} = ctx.args
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({foo, bar}),
    attributeValues: util.dynamodb.toMapValues(values),
    condition: { expression: "attribute_not_exists(id)" }
  };
}
```

根據預設，如果條件檢查失敗， AWS AppSync DynamoDB 函數會提供變動的錯誤。

不過， AWS AppSync DynamoDB 函數提供一些額外的功能，以協助開發人員處理一些常見的邊緣案例：
+ If AWS AppSync DynamoDB 函數可以判斷 DynamoDB 中的目前值是否符合所需的結果，仍會將操作視為成功。
+ 您可以設定函數來叫用自訂 Lambda 函數，以決定 AWS AppSync DynamoDB 函數應如何處理失敗，而不是傳回錯誤。

這些會在[處理條件檢查失敗](#condition-check)一節中詳細說明。

如需 DynamoDB 條件表達式的詳細資訊，請參閱 [DynamoDB ConditionExpressions 文件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)。

## 指定條件
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-specification"></a>

`PutItem`、 `UpdateItem`和 `DeleteItem`請求物件全都允許指定選用`condition`區段。若省略，則不會有條件檢查。若指定，條件必須為 true，操作才會成功。

`condition` 區段的結構如下：

```
type ConditionCheckExpression = {
  expression: string;
  expressionNames?: { [key: string]: string};
  expressionValues?: { [key: string]: any};
  equalsIgnore?: string[];
  consistentRead?: boolean;
  conditionalCheckFailedHandler?: {
    strategy: 'Custom' | 'Reject';
    lambdaArn?: string;
  };
};
```

下列欄位指定條件：

** `expression` **  
更新表達式本身。如需如何編寫條件表達式的詳細資訊，請參閱 [DynamoDB ConditionExpressions 文件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)。必須指定此欄位。

** `expressionNames` **  
表達式屬性名稱預留位置的替代，形式為索引鍵值對。索引鍵對應至*表達*式中使用的名稱預留位置，且值必須是對應於 DynamoDB 中項目屬性名稱的字串。此欄位為選用的，應只能填入於*表達式*中所用表達式屬性名稱預留位置的替代。

** `expressionValues` **  
表達式屬性值預留位置的替代，形式為索引值對。鍵對應用於表達式的值預留位置，值必須是類型值。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此必須指定。此欄位為選用的，應只能填入用於表達式中表達式屬性值預留位置的替代。

其餘欄位會告知 AWS AppSync DynamoDB 函數如何處理條件檢查失敗：

** `equalsIgnore` **  
當條件檢查在使用 `PutItem`操作時失敗時， AWS AppSync DynamoDB 函數會將目前在 DynamoDB 中的項目與嘗試寫入的項目進行比較。如果兩者相同，則操作視為成功。您可以使用 `equalsIgnore` 欄位來指定執行該比較時 AWS AppSync 應忽略的屬性清單。例如，如果唯一的差異是`version`屬性，它會將操作視為成功。此欄位為選用欄位。

** `consistentRead` **  
當條件檢查失敗時， AWS AppSync 會使用強式一致讀取，從 DynamoDB 取得項目的目前值。您可以使用此欄位，指示 AWS AppSync DynamoDB 函數改用最終一致讀取。此欄位為選用，預設值為 `true`。

** `conditionalCheckFailedHandler` **  
本節可讓您指定 AWS AppSync DynamoDB 函數在將 DynamoDB 中的目前值與預期結果進行比較後，如何處理條件檢查失敗。此區段為選用。若省略，則會預設為 `Reject` 策略。    
** `strategy` **  
 AWS AppSync DynamoDB 函數在將 DynamoDB 中的目前值與預期結果進行比較後所採用的策略。此欄位為必填，且採用下列可能值：    
** `Reject` **  
變動會失敗，並會將錯誤新增至 GraphQL 回應。  
** `Custom` **  
The AWS AppSync DynamoDB 函數會叫用自訂 Lambda 函數，以決定如何處理條件檢查失敗。當 `strategy` 設定為 `Custom`，`lambdaArn` 欄位必須包含要叫用 Lambda 函數的 ARN。  
** `lambdaArn` **  
要叫用的 Lambda 函數 ARN，決定 AWS AppSync DynamoDB 函數應如何處理條件檢查失敗。只有在 `strategy` 設定為 `Custom` 時，此欄位才必須指定。如需如何使用此功能的詳細資訊，請參閱[處理條件檢查失敗](#condition-check)。

## 處理條件檢查失敗
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-handling"></a>

當條件檢查失敗時， AWS AppSync DynamoDB 函數可以使用 `util.appendError`公用程式傳遞變動的錯誤和物件的目前值。不過， AWS AppSync DynamoDB 函數提供一些額外的功能，以協助開發人員處理一些常見的邊緣案例：
+ If AWS AppSync DynamoDB 函數可以判斷 DynamoDB 中的目前值是否符合所需的結果，仍會將操作視為成功。
+ 您可以設定函數來叫用自訂 Lambda 函數，以決定 AWS AppSync DynamoDB 函數應如何處理失敗，而不是傳回錯誤。

此程序的流程圖為：

![\[Flowchart showing process for transforming requests with mutation attempts and value checks.\]](http://docs.aws.amazon.com/zh_tw/appsync/latest/devguide/images/DynamoDB-condition-check-failure-handling.png)


### 檢查所需結果
<a name="js-checking-for-the-desired-result"></a>

當條件檢查失敗時， AWS AppSync DynamoDB 函數會執行 `GetItem` DynamoDB 請求，從 DynamoDB 取得項目的目前值。在預設情況下，它會使用強式一致性讀取，但這可使用 `condition` 區塊中的 `consistentRead` 欄位來設定，並和預期結果進行比較：
+ 對於 `PutItem`操作， AWS AppSync DynamoDB 函數會將目前的值與其嘗試寫入的值進行比較，排除`equalsIgnore`比較中列出的任何屬性。如果項目相同，它會將操作視為成功，並傳回從 DynamoDB 擷取的項目。否則，其將按照設定的策略。

  例如，如果`PutItem`請求物件看起來如下所示：

  ```
  import { util } from '@aws-appsync/utils';
  export function request(ctx) {
    const { id, name, version} = ctx.args
    return {
      operation: 'PutItem',
      key: util.dynamodb.toMapValues({foo, bar}),
      attributeValues: util.dynamodb.toMapValues({ name, version: version+1 }),
      condition: { 
        expression: "version = :expectedVersion",
        expressionValues: util.dynamodb.toMapValues({':expectedVersion': version}),
        equalsIgnore: ['version']
      }
    };
  }
  ```

  而目前在 DynamoDB 中的項目外觀如下：

  ```
  {
     "id" : { "S" : "1" },
     "name" : { "S" : "Steve" },
     "version" : { "N" : 8 }
  }
  ```

  The AWS AppSync DynamoDB 函數會將嘗試寫入的項目與目前值進行比較，查看 欄位的唯一差異，`version`但因為它設定為忽略 `version` 欄位，它會將操作視為成功，並傳回從 DynamoDB 擷取的項目。
+ 對於 `DeleteItem`操作， AWS AppSync DynamoDB 函數會檢查以確認項目已從 DynamoDB 傳回。如果沒有項目傳回，則操作視為成功。否則，其將按照設定的策略。
+ 對於 `UpdateItem`操作， AWS AppSync DynamoDB 函數沒有足夠的資訊來判斷目前在 DynamoDB 中的項目是否符合預期結果，因此遵循設定的策略。

如果 DynamoDB 中物件的目前狀態與預期結果不同， AWS AppSync DynamoDB 函數會遵循設定的策略，以拒絕變動或叫用 Lambda 函數來決定接下來要做什麼。

### 遵循「拒絕」策略
<a name="js-following-the-reject-strategy"></a>

遵循 `Reject`策略時， AWS AppSync DynamoDB 函數會傳回變動的錯誤。

例如，假設變動要求如下：

```
mutation {
    updatePerson(id: 1, name: "Steve", expectedVersion: 1) {
        Name
        theVersion
    }
}
```

如果從 DynamoDB 傳回的項目如下所示：

```
{
   "id" : { "S" : "1" },
   "name" : { "S" : "Steve" },
   "version" : { "N" : 8 }
}
```

而且函數回應處理常式如下所示：

```
import { util } from '@aws-appsync/utils';
export function response(ctx) {
  const { version, ...values } = ctx.result;
  const result = { ...values, theVersion: version };
  if (ctx.error) {
    if (error) {
      return util.appendError(error.message, error.type, result, null);
    }
  }
  return result
}
```

GraphQL 回應的外觀如下所示：

```
{
  "data": null,
  "errors": [
    {
      "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)"
      "errorType": "DynamoDB:ConditionalCheckFailedException",
      ...
    }
  ]
}
```

此外，如果傳回物件中的任何欄位皆由其他解析程式填入，且變動成功，則在 `error` 區段中傳回物件時，不會解析這些物件。

### 遵循「自訂」策略
<a name="js-following-the-custom-strategy"></a>

遵循`Custom`策略時， AWS AppSync DynamoDB 函數會叫用 Lambda 函數來決定接下來要做什麼。Lambda 函數會選擇下列其中一個選項：
+  `reject` 變動。這可讓 AWS AppSync DynamoDB 函數的行為如同設定的策略為 `Reject`，傳回 DynamoDB 中物件的變動錯誤和目前值，如上一節所述。
+  `discard` 變動。這會通知 AWS AppSync DynamoDB 函數無提示地忽略條件檢查失敗，並在 DynamoDB 中傳回 值。
+  `retry` 變動。這會通知 AWS AppSync DynamoDB 函數使用新的請求物件重試變動。

 **Lambda 叫用要求**

The AWS AppSync DynamoDB 函數會叫用 中指定的 Lambda 函數`lambdaArn`。它會使用資料來源上所設定的相同 `service-role-arn`。叫用承載的結構如下：

```
{
    "arguments": { ... },
    "requestMapping": {... },
    "currentValue": { ... },
    "resolver": { ... },
    "identity": { ... }
}
```

欄位定義如下：

** `arguments` **  
來自 GraphQL 變動的引數。這與 中請求物件可用的引數相同`context.arguments`。

** `requestMapping` **  
此操作的請求物件。

** `currentValue` **  
DynamoDB 中物件的目前值。

** `resolver` **  
有關 AWS AppSync 解析程式或函數的資訊。

** `identity` **  
發起人的相關資訊。這與 中請求物件可用的身分資訊相同`context.identity`。

承載的完整範例：

```
{
    "arguments": {
        "id": "1",
        "name": "Steve",
        "expectedVersion": 1
    },
    "requestMapping": {
        "version" : "2017-02-28",
        "operation" : "PutItem",
        "key" : {
           "id" : { "S" : "1" }
        },
        "attributeValues" : {
           "name" : { "S" : "Steve" },
           "version" : { "N" : 2 }
        },
        "condition" : {
           "expression" : "version = :expectedVersion",
           "expressionValues" : {
               ":expectedVersion" : { "N" : 1 }
           },
           "equalsIgnore": [ "version" ]
        }
    },
    "currentValue": {
        "id" : { "S" : "1" },
        "name" : { "S" : "Steve" },
        "version" : { "N" : 8 }
    },
    "resolver": {
        "tableName": "People",
        "awsRegion": "us-west-2",
        "parentType": "Mutation",
        "field": "updatePerson",
        "outputType": "Person"
    },
    "identity": {
        "accountId": "123456789012",
        "sourceIp": "x.x.x.x",
        "user": "AIDAAAAAAAAAAAAAAAAAA",
        "userArn": "arn:aws:iam::123456789012:user/appsync"
    }
}
```

 **Lambda 叫用回應** 

Lambda 函數可以檢查調用承載並套用任何商業邏輯，以決定 AWS AppSync DynamoDB 函數應如何處理失敗。處理條件檢查失敗有三個選項：
+  `reject` 變動。此選項的回應承載必須具有此架構：

  ```
  {
      "action": "reject"
  }
  ```

  這可讓 AWS AppSync DynamoDB 函數的行為如同設定的策略為 `Reject`，傳回 DynamoDB 中物件的變動和目前值的錯誤，如上節所述。
+  `discard` 變動。此選項的回應承載必須具有此架構：

  ```
  {
      "action": "discard"
  }
  ```

  這會通知 AWS AppSync DynamoDB 函數無提示地忽略條件檢查失敗，並在 DynamoDB 中傳回 值。
+  `retry` 變動。此選項的回應承載必須具有此架構：

  ```
  {
      "action": "retry",
      "retryMapping": { ... }
  }
  ```

  這會通知 AWS AppSync DynamoDB 函數使用新的請求物件重試變動。`retryMapping` 區段的結構取決於 DynamoDB 操作，並且是該操作完整請求物件的子集。

  若是 `PutItem`，`retryMapping` 區段的結構如下。如需 `attributeValues` 欄位的描述，請參閱 [PutItem](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-putitem)。

  ```
  {
      "attributeValues": { ... },
      "condition": {
          "equalsIgnore" = [ ... ],
          "consistentRead" = true
      }
  }
  ```

  若是 `UpdateItem`，`retryMapping` 區段的結構如下。如需 `update` 區段的描述，請參閱 [UpdateItem](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem)。

  ```
  {
      "update" : {
          "expression" : "someExpression"
          "expressionNames" : {
              "#foo" : "foo"
          },
          "expressionValues" : {
              ":bar" : ... typed value
          }
      },
      "condition": {
          "consistentRead" = true
      }
  }
  ```

  若是 `DeleteItem`，`retryMapping` 區段的結構如下。

  ```
  {
      "condition": {
          "consistentRead" = true
      }
  }
  ```

  無法指定使用不同的操作或索引鍵。 AWS AppSync DynamoDB 函數僅允許對相同物件重試相同的操作。此外，`condition` 區段不允許指定 `conditionalCheckFailedHandler`。如果重試失敗， AWS AppSync DynamoDB 函數會遵循 `Reject`策略。

此為 Lambda 函數處理失敗 `PutItem` 要求的範例。商業邏輯的重點是發起人為何。如果是由 提出`jeffTheAdmin`，它會重試請求，`expectedVersion`從目前在 DynamoDB 中的項目更新 `version`和 。否則，它會拒絕變動。

```
exports.handler = (event, context, callback) => {
    console.log("Event: "+ JSON.stringify(event));

    // Business logic goes here.

    var response;
    if ( event.identity.user == "jeffTheAdmin" ) {
        response = {
            "action" : "retry",
            "retryMapping" : {
                "attributeValues" : event.requestMapping.attributeValues,
                "condition" : {
                    "expression" : event.requestMapping.condition.expression,
                    "expressionValues" : event.requestMapping.condition.expressionValues
                }
            }
        }
        response.retryMapping.attributeValues.version = { "N" : event.currentValue.version.N + 1 }
        response.retryMapping.condition.expressionValues[':expectedVersion'] = event.currentValue.version

    } else {
        response = { "action" : "reject" }
    }

    console.log("Response: "+ JSON.stringify(response))
    callback(null, response)
};
```

# 交易條件表達式
<a name="js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions"></a>

交易條件表達式可在 中所有四種操作類型的請求中使用`TransactWriteItems`，即 、`PutItem``DeleteItem`、 `UpdateItem`和 `ConditionCheck`。

對於 `PutItem`、 `DeleteItem`和 `UpdateItem`，交易條件表達式是選用的。對於 `ConditionCheck`，需要交易條件表達式。

## 範例 1
<a name="js-id22"></a>

下列交易`DeleteItem`函數請求處理常式沒有條件表達式。因此，它會刪除 DynamoDB 中的項目。

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { postId } = ctx.args;
  return {
    operation: 'TransactWriteItems',
    transactItems: [
      {
        table: 'posts',
        operation: 'DeleteItem',
        key: util.dynamodb.toMapValues({ postId }),
      }
    ],
  };
}
```

## 範例 2
<a name="js-id23"></a>

下列交易`DeleteItem`函數請求處理常式確實具有交易條件表達式，只有在該文章的作者等於特定名稱時，才會允許操作成功。

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { postId, authorName} = ctx.args;
  return {
    operation: 'TransactWriteItems',
    transactItems: [
      {
        table: 'posts',
        operation: 'DeleteItem',
        key: util.dynamodb.toMapValues({ postId }),
        condition: util.transform.toDynamoDBConditionExpression({
          authorName: { eq: authorName },
        }),
      }
    ],
  };
}
```

如果條件檢查失敗，會導致 `TransactionCanceledException`，並且會在 `ctx.result.cancellationReasons` 中傳回錯誤詳細資料。請注意，根據預設，DynamoDB 中導致條件檢查失敗的舊項目會在 中傳回`ctx.result.cancellationReasons`。

## 指定條件
<a name="js-id24"></a>

`PutItem`、 `UpdateItem`和 `DeleteItem`請求物件全都允許指定選用`condition`區段。若省略，則不會有條件檢查。若指定，條件必須為 true，操作才會成功。`ConditionCheck` 必須有待指定的 `condition` 區段。條件必須為 true，整個交易才會成功。

`condition` 區段的結構如下：

```
type TransactConditionCheckExpression = {
  expression: string;
  expressionNames?: { [key: string]: string };
  expressionValues?: { [key: string]: string };
  returnValuesOnConditionCheckFailure: boolean;
};
```

下列欄位指定條件：

** `expression` **  
更新表達式本身。如需如何編寫條件表達式的詳細資訊，請參閱 [DynamoDB ConditionExpressions 文件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)。必須指定此欄位。

** `expressionNames` **  
表達式屬性名稱預留位置的替代，形式為索引鍵值對。索引鍵對應至*表達*式中使用的名稱預留位置，且值必須是對應於 DynamoDB 中項目屬性名稱的字串。此欄位為選用的，應只能填入於*表達式*中所用表達式屬性名稱預留位置的替代。

** `expressionValues` **  
表達式屬性值預留位置的替代，形式為索引值對。鍵對應用於表達式的值預留位置，值必須是類型值。如需如何指定「輸入值」的詳細資訊，請參閱[類型系統 （請求映射）](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)。此必須指定。此欄位為選用的，應只能填入用於表達式中表達式屬性值預留位置的替代。

** `returnValuesOnConditionCheckFailure` **  
指定是否在條件檢查失敗時擷取 DynamoDB 中的項目。擷取的項目將位於 `ctx.result.cancellationReasons[<index>].item` 中，其中 `<index>` 是條件檢查失敗之請求項目的索引。此值預設為 true。

# 投影
<a name="js-aws-appsync-resolver-reference-dynamodb-projections"></a>

使用 `GetItem`、`BatchGetItem`、、 `Scan` `Query`和 `TransactGetItems`操作讀取 DynamoDB 中的物件時，您可以選擇指定投影，以識別您想要的屬性。投影屬性具有下列結構，類似於篩選條件：

```
type DynamoDBExpression = {
  expression: string;
  expressionNames?: { [key: string]: string}
};
```

欄位定義如下：

** `expression` **  
投影表達式，這是字串。若要擷取單一屬性，請指定其名稱。對於多個屬性，名稱必須是逗號分隔值。如需撰寫投影表達式的詳細資訊，請參閱 [DynamoDB 投影表達](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ProjectionExpressions.html)式文件。此欄位為必填。

** `expressionNames` **  
以鍵/值對形式取代表達式屬性*名稱*預留位置。索引鍵對應至用於 `expression` 的名稱預留位置。值必須是對應於 DynamoDB 中項目屬性名稱的字串。此欄位是選用的，應僅填入 中使用的表達式屬性名稱預留位置的替換`expression`。如需 的詳細資訊`expressionNames`，請參閱 [DynamoDB 文件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeNames.html)。

## 範例 1
<a name="js-id22"></a>

下列範例是 JavaScript 函數的投影區段，其中只有屬性 `id` `author`和 會從 DynamoDB 傳回：

```
projection : {
    expression : "#author, id",
    expressionNames : {
        "#author" : "author"
    }
}
```

**提示**  
您可以使用 [selectionSetList](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html#aws-appsync-resolver-context-reference-info-js) 存取 GraphQL 請求選取集。此欄位可讓您根據您的需求動態架構投影表達式。

**注意**  
搭配 `Query`和 `Scan`操作使用投影表達式時， 的值`select`必須是 `SPECIFIC_ATTRIBUTES`。如需詳細資訊，請參閱 [DynamoDB 文件](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html#DDB-Query-request-Select)。

# OpenSearch 的AWS AppSync JavaScript 解析程式函數參考
<a name="resolver-reference-elasticsearch-js"></a>

Amazon OpenSearch Service 的 AWS AppSync 解析程式可讓您使用 GraphQL 在帳戶中現有的 OpenSearch Service 網域中存放和擷取資料。此解析程式的運作方式是允許您將傳入的 GraphQL 請求映射至 OpenSearch Service 請求，然後將 OpenSearch Service 回應映射回 GraphQL。本節說明支援的 OpenSearch Service 操作的函數請求和回應處理常式。

## 請求
<a name="request-js"></a>

大多數 OpenSearch Service 請求物件都有共同的結構，其中只有幾個部分變更。下列範例會根據 OpenSearch Service 網域執行搜尋，其中文件類型為 ，`post`並在 下編製索引`id`。搜尋參數定義於 `body` 區段，許多常見的查詢子句定義於 `query` 欄位。此範例將搜尋在 `"Nadia"` 欄位中包含 `"Bailey"` 或 `author` (或兩者) 的文件：

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/post/_search',
    params: {
      headers: {},
      queryString: {},
      body: {
        from: 0,
        size: 50,
        query: {
          bool: {
            should: [
              { match: { author: 'Nadia' } },
              { match: { author: 'Bailey' } },
            ],
          },
        },
      },
    },
  };
}
```

## 回應
<a name="response-mapping-template"></a>

如同其他資料來源，OpenSearch Service 會將回應傳送至需要轉換為 GraphQL 的 AWS AppSync。

大多數 GraphQL 查詢正在從 OpenSearch Service 回應中尋找 `_source` 欄位。由於您可以執行搜尋以傳回個別文件或文件清單，因此 OpenSearch Service 中有兩種常用的回應模式：

 **結果清單** 

```
export function response(ctx) {
  const entries = [];
  for (const entry of ctx.result.hits.hits) {
    entries.push(entry['_source']);
  }
  return entries;
}
```

 **個別項目** 

```
export function response(ctx) {
  return ctx.result['_source']
}
```

## `operation` 欄位
<a name="operation-field"></a>

**注意**  
這僅適用於請求處理常式。

 AWS AppSync 傳送至 OpenSearch Service 網域的 HTTP 方法或動詞 (GET、POST、PUT、HEAD 或 DELETE)。金鑰與值皆必須為字串。

```
"operation" : "PUT"
```

## `path` 欄位
<a name="path-field"></a>

**注意**  
這僅適用於請求處理常式。

來自 AWS AppSync 的 OpenSearch Service 請求的搜尋路徑。這會形成操作的 HTTP 動詞的 URL。金鑰與值皆必須為字串。

```
"path" : "/indexname/type"

"path" : "/indexname/type/_search"
```

評估請求處理常式時，此路徑會做為 HTTP 請求的一部分傳送，包括 OpenSearch Service 網域。例如，之前的範例可轉譯為：

```
GET https://opensearch-domain-name.REGION.es.amazonaws.com/indexname/type/_search
```

## `params` 欄位
<a name="params-field"></a>

**注意**  
這僅適用於請求處理常式。

用來指定搜尋執行的動作，最常見的方式是設定**內文**內的**查詢**值。不過，有多項其他功能可設定，例如回應的格式。
+  **標頭** 

  標頭資訊，以金鑰值對形式。金鑰與值皆必須為字串。例如：

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

   
**注意**  
AWS AppSync 目前僅支援 JSON 做為 `Content-Type`。
+  **queryString** 

  金鑰值對，指定常見的選項，例如 JSON 回應的程式碼格式。金鑰與值皆必須為字串。例如，如果您希望獲得非常完整格式的 JSON，請使用：

  ```
  "queryString" : {
      "pretty" : "true"
  }
  ```
+  **本文** 

  這是請求的主要部分，允許 AWS AppSync 為您的 OpenSearch Service 網域製作格式正確的搜尋請求。金鑰必須是由物件組成的字串。以下顯示幾個示範。

 **範例 1** 

傳回城市符合「seattle」的所有文件：

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/post/_search',
    params: {
      headers: {},
      queryString: {},
      body: { from: 0, size: 50, query: { match: { city: 'seattle' } } },
    },
  };
}
```

 **範例 2** 

傳回所有符合「washington」做為城市或州的文件：

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/post/_search',
    params: {
      headers: {},
      queryString: {},
      body: {
        from: 0,
        size: 50,
        query: {
          multi_match: { query: 'washington', fields: ['city', 'state'] },
        },
      },
    },
  };
}
```

## 傳遞變數
<a name="passing-variables"></a>

**注意**  
這僅適用於請求處理常式。

您也可以在請求處理常式中將變數作為評估的一部分傳遞。例如，假設您有一個 GraphQL 查詢如下：

```
query {
    searchForState(state: "washington"){
        ...
    }
}
```

函數請求處理常式可以是下列項目：

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/post/_search',
    params: {
      headers: {},
      queryString: {},
      body: {
        from: 0,
        size: 50,
        query: {
          multi_match: { query: ctx.args.state, fields: ['city', 'state'] },
        },
      },
    },
  };
}
```

# Lambda 的AWS AppSync JavaScript 解析程式函數參考
<a name="resolver-reference-lambda-js"></a>

您可以使用 AWS AppSync 函數和解析程式來調用您帳戶中的 Lambda 函數。您可以在將請求承載傳回給用戶端之前，從 Lambda 函數塑造請求承載和回應。您也可以指定要在請求物件中執行的操作類型。本節說明支援 Lambda 操作的請求。

## 請求物件
<a name="request-object-js"></a>

Lambda 請求物件會處理與 Lambda 函數相關的欄位：

```
export type LambdaRequest = {
  operation: 'Invoke' | 'BatchInvoke';
  invocationType?: 'RequestResponse' | 'Event';
  payload: unknown;
};
```

以下是使用 `invoke`操作的範例，其承載資料是來自 GraphQL 結構描述`getPost`的欄位，以及來自內容的引數：

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    payload: { field: 'getPost', arguments: ctx.args },
  };
}
```

整個映射文件會做為 Lambda 函數的輸入傳遞，因此先前的範例現在如下所示：

```
{
  "operation": "Invoke",
  "payload": {
    "field": "getPost",
    "arguments": {
      "input": {
        "id": "postId1",
      }
    }
  }
}
```

### 作業
<a name="operation-js"></a>

Lambda 資料來源可讓您在 `operation` 欄位中定義兩個操作： `Invoke`和 `BatchInvoke`。`Invoke` 操作 lets AWS AppSync 知道 會為每個 GraphQL 欄位解析程式呼叫 Lambda 函數。`BatchInvoke`instructs AWS AppSync 會批次處理目前 GraphQL 欄位的請求。`operation` 欄位是必要的。

對於 `Invoke`，解析的請求符合 Lambda 函數的輸入承載。讓我們修改上述範例：

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    payload: { field: 'getPost', arguments: ctx.args },
  };
}
```

這會解決並傳遞給 Lambda 函數，看起來可能會類似這樣：

```
{
  "operation": "Invoke",
  "payload": {
    "arguments": {
      "id": "postId1"
    }
  }
}
```

對於 `BatchInvoke`，請求會套用至批次中的每個欄位解析程式。為了簡潔起見， AWS AppSync 會將所有請求`payload`值合併到符合請求物件之單一物件下的清單中。下列範例請求處理常式會顯示合併：

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    payload: ctx,
  };
}
```

此請求會經過評估並解析為下列映射文件：

```
{
  "operation": "BatchInvoke",
  "payload": [
    {...}, // context for batch item 1
    {...}, // context for batch item 2
    {...}  // context for batch item 3
  ]
}
```

`payload` 清單的每個元素都會對應至單一批次項目。Lambda 函數也預期會傳回符合請求中傳送項目順序的清單形狀回應：

```
[
  { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 1
  { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 2
  { "data": {...}, "errorMessage": null, "errorType": null }  // result for batch item 3
]
```

### 酬載
<a name="payload-js"></a>

`payload` 欄位是用來將任何資料傳遞至 Lambda 函數的容器。如果 `operation` 欄位設定為 `BatchInvoke`， AWS AppSync 會將現有的`payload`值包裝在清單中。此 `payload` 欄位為選用。

### 調用類型
<a name="async-invocation-type-js"></a>

Lambda 資料來源可讓您定義兩種叫用類型： `RequestResponse`和 `Event`。調用類型與 [Lambda API](https://docs.aws.amazon.com//lambda/latest/api/API_Invoke.html) 中定義的調用類型同義。`RequestResponse` 叫用類型 lets AWS AppSync 會同步呼叫您的 Lambda 函數，以等待回應。`Event` 調用可讓您以非同步方式調用 Lambda 函數。如需 Lambda 如何處理`Event`調用類型請求的詳細資訊，請參閱[非同步調用](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html)。此 `invocationType` 欄位為選用。如果請求中未包含此欄位， AWS AppSync 會預設為`RequestResponse`叫用類型。

對於任何`invocationType`欄位，解析的請求符合 Lambda 函數的輸入承載。讓我們修改上述範例：

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    invocationType: 'Event',
    payload: { field: 'getPost', arguments: ctx.args },
  };
}
```

這會解決並傳遞給 Lambda 函數，看起來可能會類似這樣：

```
{
  "operation": "Invoke",
  "invocationType": "Event",
  "payload": {
    "arguments": {
      "id": "postId1"
    }
  }
}
```

當`BatchInvoke`操作與`Event`調用類型欄位搭配使用時， AWS AppSync 會以上述相同方式合併欄位解析程式，並將請求做為非同步事件傳遞給您的 Lambda 函數，而 `payload`為值清單。`Event` 呼叫類型請求的回應會產生沒有回應處理常式`null`的值：

```
{
  "data": {
    "field": null
  }
}
```

我們建議您停用`Event`呼叫類型解析程式的解析程式快取，因為如果有快取命中，這些解析程式不會傳送至 Lambda。

## 回應物件
<a name="response-object-js"></a>

如同其他資料來源，您的 Lambda 函數會將回應傳送至 AWS AppSync，該回應必須轉換為 GraphQL 類型。Lambda 函數的結果包含在`context`結果屬性 () 中`context.result`。

如果 Lambda 函數回應的形狀符合 GraphQL 類型的形狀，您可以使用下列函數回應處理常式轉送回應：

```
export function response(ctx) {
  return ctx.result
}
```

沒有套用至回應物件的必要欄位或形狀限制。不過，由於 GraphQL 是強式輸入，因此解析的回應必須符合預期的 GraphQL 類型。

## Lambda 函數批次回應
<a name="aws-appsync-resolver-reference-lambda-batched-response-js"></a>

如果 `operation` 欄位設定為 `BatchInvoke`， AWS AppSync 預期會從 Lambda 函數傳回項目清單。為了讓 AWS AppSync 將每個結果對應回原始請求項目，回應清單的大小和順序必須相符。在回應清單中有`null`項目是有效的；相應地`ctx.result`設定為 *null*。

# EventBridge 資料來源的AWS AppSync JavaScript 解析程式函數參考
<a name="resolver-reference-eventbridge-js"></a>

搭配 EventBridge 資料來源使用的 AWS AppSync 解析程式函數請求和回應可讓您將自訂事件傳送至 Amazon EventBridge 匯流排。

## 請求
<a name="request-js"></a>

請求處理常式可讓您將多個自訂事件傳送至 EventBridge 事件匯流排：

```
export function request(ctx) {
  return {
    "operation" : "PutEvents",
    "events" : [{}]
  }
}
```

EventBridge `PutEvents`請求具有下列類型定義：

```
type PutEventsRequest = {
  operation: 'PutEvents'
  events: {
    source: string
    detail: { [key: string]: any }
    detailType: string
    resources?: string[]
    time?: string // RFC3339 Timestamp format
  }[]
}
```

## 回應
<a name="response-js"></a>

如果`PutEvents`操作成功，EventBridge 的回應會包含在 中`ctx.result`：

```
export function response(ctx) {
  if(ctx.error)
    util.error(ctx.error.message, ctx.error.type, ctx.result)
  else
    return ctx.result
}
```

執行 `InternalExceptions`或 等`PutEvents`操作時發生的錯誤`Timeouts`會出現在 中`ctx.error`。如需 EventBridge 常見錯誤的清單，請參閱 [EventBridge 常見錯誤參考](https://docs.aws.amazon.com/eventbridge/latest/APIReference/CommonErrors.html)。

`result` 將具有下列類型定義：

```
type PutEventsResult = {
  Entries: {
    ErrorCode: string
    ErrorMessage: string
    EventId: string
  }[]
  FailedEntryCount: number
}
```
+ **項目**

  擷取的事件結果成功和失敗。如果擷取成功，則項目`EventID`中會有 。否則，您可以使用 `ErrorCode`和 `ErrorMessage` 來識別項目的問題。

  對於每個記錄，回應元素的索引與請求陣列中的索引相同。
+ **FailedEntryCount**

  失敗項目的數量。此值以整數表示。

如需 回應的詳細資訊`PutEvents`，請參閱 [PutEvents](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutEvents.html#API_PutEvents_ResponseElements)。

**範例回應 1**

下列範例是具有兩個成功事件`PutEvents`的操作：

```
{
    "Entries" : [ 
        {
            "EventId": "11710aed-b79e-4468-a20b-bb3c0c3b4860"
        }, 
        {
            "EventId": "d804d26a-88db-4b66-9eaf-9a11c708ae82"
        }
    ],
    "FailedEntryCount" : 0
}
```

**範例回應 2**

下列範例是具有三個事件、兩個成功和一個失敗`PutEvents`的操作：

```
{
    "Entries" : [ 
        {
            "EventId": "11710aed-b79e-4468-a20b-bb3c0c3b4860"
        }, 
        {
            "EventId": "d804d26a-88db-4b66-9eaf-9a11c708ae82"
        },
        {
            "ErrorCode" : "SampleErrorCode",
            "ErrorMessage" : "Sample Error Message"
        }
    ],
    "FailedEntryCount" : 1
}
```

## `PutEvents` 欄位
<a name="putevents-field"></a>

`PutEvents` 包含下列映射範本欄位：
+ **版本**

  在所有請求映射範本中， `version` 欄位會定義範本使用的版本。此欄位為必填。此值`2018-05-29`是 EventBridge 映射範本唯一支援的版本。
+ **操作**

  唯一支援的操作是 `PutEvents`。此操作可讓您將自訂事件新增至事件匯流排。
+ **事件**

  將新增至事件匯流排的事件陣列。此陣列的配置應為 1 - 10 個項目。

  `Event` 物件包含以下欄位：
  + `"source"`：定義事件來源的字串。
  + `"detail"`：您可以用來連接事件相關資訊的 JSON 物件。此欄位可以是空的映射 `{ }` ()。
  + `"detailType`：識別事件類型的字串。
  + `"resources"`：可識別事件中所涉及資源的字串 JSON 陣列。此欄位可以是空陣列。
  + `"time"`：以字串提供的事件時間戳記。這應該遵循 [RFC3339](https://www.rfc-editor.org/rfc/rfc3339.txt) 時間戳記格式。

以下程式碼片段是一些有效`Event`物件的範例：

**範例 1**

```
{
    "source" : "source1",
    "detail" : {
        "key1" : [1,2,3,4],
        "key2" : "strval"
    },
    "detailType" : "sampleDetailType",
    "resources" : ["Resouce1", "Resource2"],
    "time" : "2022-01-10T05:00:10Z"
}
```

**範例 2**

```
{
    "source" : "source1",
    "detail" : {},
    "detailType" : "sampleDetailType"
}
```

**範例 3**

```
{
    "source" : "source1",
    "detail" : {
        "key1" : 1200
    },
    "detailType" : "sampleDetailType",
    "resources" : []
}
```

# `None` 資料來源的AWS AppSync JavaScript 解析程式函數參考
<a name="resolver-reference-none-js"></a>

The AWS AppSync 解析程式函數請求和類型為 *None* 的資料來源回應可讓您塑造 AWS AppSync 本機操作的請求。

## 請求
<a name="request-js"></a>

請求處理常式可能很簡單，可讓您透過 `payload` 欄位盡可能傳遞內容資訊。

```
type NONERequest = {
  payload: any;
};
```

以下是 欄位引數傳遞至承載的範例：

```
export function request(ctx) {
  return {
    payload: context.args
  };
}
```

`payload` 欄位的值會轉送至函數回應處理常式，並可在 中使用`context.result`。

## 酬載
<a name="payload-js"></a>

`payload` 欄位是一種容器，可用來傳遞任何資料，然後提供給函數回應處理常式。

 此 `payload` 欄位為選用。

## 回應
<a name="response-js"></a>

由於沒有資料來源， `payload` 欄位的值會轉送至函數回應處理常式，並在 `context.result` 屬性上設定 。

如果`payload`欄位值的形狀完全符合 GraphQL 類型的形狀，您可以使用下列回應處理常式轉送回應：

```
export function response(ctx) {
  return ctx.result;
}
```

沒有套用至傳回回應的必要欄位或形狀限制。不過，由於 GraphQL 是強式輸入，因此解析的回應必須符合預期的 GraphQL 類型。

# HTTP 的AWS AppSync JavaScript 解析程式函數參考
<a name="resolver-reference-http-js"></a>

 AWS AppSync HTTP 解析程式函數可讓您將來自 AWS AppSync 的請求傳送至任何 HTTP 端點，並將 HTTP 端點的回應傳回至 AWS AppSync。使用請求處理常式，您可以向 AWS AppSync 提供有關要叫用之操作性質的提示。本節說明支援 HTTP 解析程式的不同組態。

## 請求
<a name="request-js"></a>

```
type HTTPRequest = {
  method: 'PUT' | 'POST' | 'GET' | 'DELETE' | 'PATCH';
  params?: {
    query?: { [key: string]: any };
    headers?: { [key: string]: string };
    body?: any;
  };
  resourcePath: string;
};
```

下列程式碼片段是具有`text/plain`內文的 HTTP POST 請求範例：

```
export function request(ctx) {
  return {
    method: 'POST',
    params: {
      headers: { 'Content-Type': 'text/plain' },
      body: 'this is an example of text body',
    },
    resourcePath: '/',
  };
}
```

## Method
<a name="method-js"></a>

**注意**  
這僅適用於請求處理常式。

 AWS AppSync 傳送至 HTTP 端點的 HTTP 方法或動詞 (GET、POST、PUT、PATCH 或 DELETE)。

```
"method": "PUT"
```

## ResourcePath
<a name="resourcepath-js"></a>

 

**注意**  
這僅適用於請求處理常式。

您要存取的資源路徑。除了 HTTP 資料來源中的端點之外，資源路徑也會形成 AWS AppSync 服務發出請求的 URL。

```
"resourcePath": "/v1/users"
```

評估請求時，此路徑會做為 HTTP 請求的一部分傳送，包括 HTTP 端點。例如，之前的範例可轉譯如下：

```
PUT <endpoint>/v1/users
```

## 參數欄位
<a name="params-field-js"></a>

**注意**  
這僅適用於請求處理常式。

用來指定搜尋執行的動作，最常見的方式是設定**內文**中的**查詢**值。不過，有多項其他功能可設定，例如回應的格式。

** **標頭** **  
標頭資訊，以金鑰值對形式。金鑰與值皆必須為字串。  
例如：  

```
"headers" : {
    "Content-Type" : "application/json"
}
```
目前支援的 `Content-Type` 標頭包括：  

```
text/*
application/xml
application/json
application/soap+xml
application/x-amz-json-1.0
application/x-amz-json-1.1
application/vnd.api+json
application/x-ndjson
```
您無法設定下列 HTTP 標頭：  

```
HOST
CONNECTION
USER-AGENT
EXPECTATION
TRANSFER_ENCODING
CONTENT_LENGTH
```

** **query** **  
金鑰值對，指定常見的選項，例如 JSON 回應的程式碼格式。金鑰與值皆必須為字串。以下範例顯示如何傳送 `?type=json` 查詢字串：  

```
"query" : {
    "type" : "json"
}
```

** **本文** **  
此本文包含您選擇設定的 HTTP 請求本文。除非內容類型指定字元集，否則請求本文一律是 UTF-8 編碼的字串。  

```
"body":"body string"
```

## 回應
<a name="response-js"></a>

請見[此處](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-http-resolvers-js.html)範例。

# Amazon RDS 的AWS AppSync JavaScript 解析程式函數參考
<a name="resolver-reference-rds-js"></a>

 AWS AppSync RDS 函數和解析程式可讓開發人員使用 RDS Data API 將SQL查詢傳送至 Amazon Aurora 叢集資料庫，並取回這些查詢的結果。您可以使用 AWS AppSync`rds`的模組標記範本或使用`rds`模組的 `select`、`update`、 `insert`和 `remove` helper 函數來寫入傳送到資料 API 的SQL陳述`sql`式。 AWS AppSync 會利用 RDS Data Service [https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_ExecuteStatement.html](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_ExecuteStatement.html)的動作，對資料庫執行 SQL 陳述式。

**主題**
+ [SQL 標記範本](#sql-tagged-templates)
+ [建立陳述式](#creating-statements)
+ [擷取資料](#retrieving-data)
+ [公用程式函數](#utility-functions)
+ [SQL Select](#utility-functions-select)
+ [SQL 插入](#utility-functions-insert)
+ [SQL 更新](#utility-functions-update)
+ [SQL 刪除](#utility-functions-delete)
+ [轉換](#casting)

## SQL 標記範本
<a name="sql-tagged-templates"></a>

AWS AppSync的`sql`標記範本可讓您建立靜態陳述式，以使用範本表達式在執行時間接收動態值。 會從表達式值 AWS AppSync 建置變數映射，以建構傳送至 Amazon Aurora Serverless Data API 的[https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html)查詢。使用此方法時，執行時間傳遞的動態值無法修改原始陳述式，這可能會導致意外執行。所有動態值都會以參數形式傳遞，無法修改原始陳述式，也不會由資料庫執行。這會使您的查詢較不易受到SQL注入攻擊。

**注意**  
在所有情況下，撰寫SQL陳述式時，您應該遵循安全準則，以正確處理作為輸入的接收資料。

**注意**  
`sql` 標記的範本僅支援傳遞變數值。您無法使用表達式動態指定資料欄或資料表名稱。不過，您可以使用公用程式函數來建置動態陳述式。

在下列範例中，我們會建立查詢，根據在執行時間於 GraphQL 查詢中動態設定的`col`引數值進行篩選。此值只能使用標籤表達式新增至 陳述式：

```
import { sql, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
  const query = sql`
SELECT * FROM table 
WHERE column = ${ctx.args.col}`
  ;
  return createMySQLStatement(query);
}
```

透過透過變數映射傳遞所有動態值，我們依賴資料庫引擎安全地處理和淨化值。

## 建立陳述式
<a name="creating-statements"></a>

函數和解析程式可以與 MySQL 和 PostgreSQL 資料庫互動。`createPgStatement` 分別使用 `createMySQLStatement`和 來建置陳述式。例如， `createMySQLStatement`可以建立 MySQL 查詢。這些函數接受最多兩個陳述式，當請求應該立即擷取結果時很有用。使用 MySQL，您可以執行下列動作：

```
import { sql, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { id, text } = ctx.args;
    const s1 = sql`insert into Post(id, text) values(${id}, ${text})`;
    const s2 = sql`select * from Post where id = ${id}`;
    return createMySQLStatement(s1, s2);
}
```

**注意**  
`createPgStatement` 和 `createMySQLStatement`不會逸出或使用`sql`標記範本建置的陳述式或引號。

## 擷取資料
<a name="retrieving-data"></a>

執行的 SQL 陳述式結果可在 `context.result` 物件的回應處理常式中使用。結果是 JSON 字串，其中包含來自 `ExecuteStatement`動作的[回應元素](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_ExecuteStatement.html#API_ExecuteStatement_ResponseElements)。剖析時，結果的形狀如下：

```
type SQLStatementResults = {
    sqlStatementResults: {
        records: any[];
        columnMetadata: any[];
        numberOfRecordsUpdated: number;
        generatedFields?: any[]
    }[]
}
```

您可以使用 `toJsonObject`公用程式，將結果轉換為代表傳回資料列的 JSON 物件清單。例如：

```
import { toJsonObject } from '@aws-appsync/utils/rds';

export function response(ctx) {
    const { error, result } = ctx;
    if (error) {
        return util.appendError(
            error.message,
            error.type,
            result
        )
    }
    return toJsonObject(result)[1][0]
}
```

請注意， `toJsonObject`會傳回一組陳述式結果。如果您提供了一個陳述式，則陣列長度為 `1`。如果您提供兩個陳述式，則陣列長度為 `2`。陣列中的每個結果都包含 `0` 或多個資料列。`null`如果結果值無效或非預期， 會`toJsonObject`傳回 。

## 公用程式函數
<a name="utility-functions"></a>

您可以使用 AWS AppSync RDS 模組的公用程式協助程式來與資料庫互動。

### SQL Select
<a name="utility-functions-select"></a>

`select` 公用程式會建立 `SELECT`陳述式來查詢您的關聯式資料庫。

**基本使用**

以其基本形式，您可以指定要查詢的資料表：

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement: 
    // "SELECT * FROM "persons"
    return createPgStatement(select({table: 'persons'}));
}
```

請注意，您也可以在資料表識別符中指定結構描述：

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement:
    // SELECT * FROM "private"."persons"
    return createPgStatement(select({table: 'private.persons'}));
}
```

**指定資料欄**

您可以使用 `columns` 屬性指定資料欄。如果未將此值設定為 ，則預設為 `*`：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name']
    }));
}
```

您也可以指定資料欄的資料表：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "persons"."name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'persons.name']
    }));
}
```

**限制和位移**

您可以套用 `limit`和 `offset`至查詢：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name"
    // FROM "persons"
    // LIMIT :limit
    // OFFSET :offset
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        limit: 10,
        offset: 40
    }));
}
```

**排序依據**

您可以使用 `orderBy` 屬性來排序結果。提供指定 欄和選用 `dir` 屬性的物件陣列：

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name" FROM "persons"
    // ORDER BY "name", "id" DESC
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        orderBy: [{column: 'name'}, {column: 'id', dir: 'DESC'}]
    }));
}
```

**篩選條件**

您可以使用特殊條件物件來建置篩選條件：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}}
    }));
}
```

您也可以合併篩選條件：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME and "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}, id: {gt: 10}}
    }));
}
```

您也可以建立`OR`陳述式：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME OR "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { or: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

您也可以使用 否定條件`not`：

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE NOT ("name" = :NAME AND "id" > :ID)
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { not: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

您也可以使用下列運算子來比較值：


| 
| 
| 運算子 | Description | 可能的值類型 | 
| --- |--- |--- |
| eq | Equal | number, string, boolean | 
| ne | Not equal | number, string, boolean | 
| le | Less than or equal | number, string | 
| lt | Less than | number, string | 
| ge | Greater than or equal | number, string | 
| gt | Greater than | number, string | 
| contains | Like | string | 
| notContains | Not like | string | 
| beginsWith | Starts with prefix | string | 
| between | Between two values | number, string | 
| attributeExists | The attribute is not null | number, string, boolean | 
| size | checks the length of the element | string | 

### SQL 插入
<a name="utility-functions-insert"></a>

`insert` 公用程式提供使用 `INSERT`操作在資料庫中插入單一資料列項目的直接方式。

**單一項目插入**

若要插入項目，請指定 資料表，然後傳入值的物件。物件索引鍵會映射到您的資料表資料欄。資料欄名稱會自動逸出，並使用變數映射將值傳送至資料庫：

```
import { insert, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({ table: 'persons', values });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    return createMySQLStatement(insertStatement)
}
```

**MySQL 使用案例**

您可以結合 `insert`後接 `select`來擷取插入的資料列：

```
import { insert, select, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({  table: 'persons', values });
    const selectStatement = select({
        table: 'persons',
        columns: '*',
        where: { id: { eq: values.id } },
        limit: 1,
    });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    // and
    // SELECT *
    // FROM `persons`
    // WHERE `id` = :ID
    return createMySQLStatement(insertStatement, selectStatement)
}
```

**Postgres 使用案例**

透過 Postgres，您可以使用 從您插入的資料列[https://www.postgresql.org/docs/current/dml-returning.html](https://www.postgresql.org/docs/current/dml-returning.html)取得資料。它接受 `*`或一組資料欄名稱：

```
import { insert, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({
        table: 'persons',
        values,
        returning: '*'
    });

    // Generates statement:
    // INSERT INTO "persons"("name")
    // VALUES(:NAME)
    // RETURNING *
    return createPgStatement(insertStatement)
}
```

### SQL 更新
<a name="utility-functions-update"></a>

`update` 公用程式可讓您更新現有的資料列。您可以使用 條件物件，將變更套用至滿足條件的所有資料列中的指定資料欄。例如，假設我們有一個結構描述，允許我們進行此變動。我們希望以 `Person` `id`的值更新 `name` 的 ，`3`但前提是我們從 開始知道它們 (`known_since`)`2000`：

```
mutation Update {
    updatePerson(
        input: {id: 3, name: "Jon"},
        condition: {known_since: {ge: "2000"}}
    ) {
    id
    name
  }
}
```

我們的更新解析程式如下所示：

```
import { update, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id, ...values }, condition } = ctx.args;
    const where = {
        ...condition,
        id: { eq: id },
    };
    const updateStatement = update({
        table: 'persons',
        values,
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // UPDATE "persons"
    // SET "name" = :NAME, "birthday" = :BDAY, "country" = :COUNTRY
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

我們可以將檢查新增至條件，以確保只會更新主索引鍵`id`等於 `3` 的資料列。同樣地，對於 Postgres `inserts`，您可以使用 `returning` 來傳回修改後的資料。

### SQL 刪除
<a name="utility-functions-delete"></a>

`remove` 公用程式可讓您刪除現有的資料列。您可以在滿足條件的所有資料列上使用條件物件。請注意， `delete` 是 JavaScript 中的預留關鍵字。 `remove` 應該改用：

```
import { remove, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id }, condition } = ctx.args;
    const where = { ...condition, id: { eq: id } };
    const deleteStatement = remove({
        table: 'persons',
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // DELETE "persons"
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

## 轉換
<a name="casting"></a>

在某些情況下，您可能希望在陳述式中使用有關正確物件類型的更具體性。您可以使用提供的類型提示來指定參數的類型。 AWS AppSync 支援與資料 API [相同的類型提示](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html#rdsdtataservice-Type-SqlParameter-typeHint)。您可以使用 模組的 `typeHint`函數來 AWS AppSync `rds`轉換參數。

下列範例可讓您將陣列做為值傳送，該值會轉換為 JSON 物件。我們使用 `->`運算子來擷取 JSON 陣列`index``2`中 的 元素：

```
import { sql, createPgStatement, toJsonObject, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const arr = ctx.args.list_of_ids
    const statement = sql`select ${typeHint.JSON(arr)}->2 as value`
    return createPgStatement(statement)
}

export function response(ctx) {
    return toJsonObject(ctx.result)[0][0].value
}
```

在處理和比較 `DATE`、 和 時`TIME`，投射也很有用`TIMESTAMP`：

```
import { select, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const when = ctx.args.when
    const statement = select({
        table: 'persons',
        where: { createdAt : { gt: typeHint.DATETIME(when) } }
    })
    return createPgStatement(statement)
}
```

以下另一個範例示範如何傳送目前的日期和時間：

```
import { sql, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const now = util.time.nowFormatted('YYYY-MM-dd HH:mm:ss')
    return createPgStatement(sql`select ${typeHint.TIMESTAMP(now)}`)
}
```

**可用的類型提示**
+ `typeHint.DATE` - 對應的參數會以 `DATE`類型的物件傳送至資料庫。接受的格式為 `YYYY-MM-DD`。
+ `typeHint.DECIMAL` - 對應的參數會以 `DECIMAL`類型的物件傳送至資料庫。
+ `typeHint.JSON` - 對應的參數會以 `JSON`類型的物件傳送至資料庫。
+ `typeHint.TIME` - 對應的字串參數值會以 `TIME`類型的物件傳送至資料庫。接受的格式為 `HH:MM:SS[.FFF]`。
+ `typeHint.TIMESTAMP` - 對應的字串參數值會以 `TIMESTAMP`類型的物件傳送至資料庫。接受的格式為 `YYYY-MM-DD HH:MM:SS[.FFF]`。
+ `typeHint.UUID` - 對應的字串參數值會以 `UUID`類型的物件傳送至資料庫。

# Amazon Bedrock 執行時間的AWS AppSync JavaScript 解析程式和函數參考
<a name="resolver-reference-bedrock-js"></a>

您可以使用 AWS AppSync 函數和解析程式，在 中的 Amazon Bedrock 上叫用模型 AWS 帳戶。您可以在將請求承載傳回給用戶端之前，從模型叫用函數中塑造請求承載和回應。您可以使用 Amazon Bedrock 執行時間的 `InvokeModel` API 或 `Converse` API。本節說明支援 Amazon Bedrock 操作的請求。

**注意**  
AWS AppSync 僅支援在 10 秒內完成的同步調用。無法呼叫 Amazon Bedrock 的串流 APIs。 AWS AppSync 僅支援在與 AWS AppSync API 相同的區域中叫用基礎模型和[推論描述](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles.html)檔。

## 請求物件
<a name="request_object"></a>

`InvokeModel` 請求物件可讓您與 Amazon Bedrock 的 `InvokeModel` API 互動。

```
type BedrockInvokeModelRequest = {
  operation: 'InvokeModel';
  modelId: string;
  body: any;
  guardrailIdentifier?: string;
  guardrailVersion?: string;
  guardrailTrace?: string;
}
```

`Converse` 請求物件可讓您與 Amazon Bedrock 的 `Converse` API 互動。

```
type BedrockConverseRequest = {
  operation: 'Converse';
  modelId: string;
  messages: BedrockMessage[];
  additionalModelRequestFields?: any;
  additionalModelResponseFieldPaths?: string[];
  guardrailConfig?: BedrockGuardrailConfig;
  inferenceConfig?: BedrockInferenceConfig;
  promptVariables?: { [key: string]: BedrockPromptVariableValues }[];
  system?: BedrockSystemContent[];
  toolConfig?: BedrockToolConfig;
}
```

如需詳細資訊，請參閱本主題稍後的 [類型參考](#type-reference-bedrock)一節。

您可以從函數和解析程式直接建置請求物件，或使用 @aws-appsync/utils/ai 的協助程式函數來建立請求。在請求中指定模型 ID (modelId) 時，您可以使用模型 ID 或模型 ARN。

下列範例使用 `invokeModel`函數來摘要使用 Amazon Titan Text G1 - Lite (amazon.titan-text-lite-v1) 的文字。設定的護欄用於識別和封鎖或篩選提示流程中不需要的內容。請參閱《[Amazon Bedrock 使用者指南》，進一步了解 Amazon Bedrock Guardrails](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html)。 **

**重要**  
您負責安全的應用程式開發和防止漏洞，例如提示注入。若要進一步了解，請參閱《*Amazon Bedrock 使用者指南*》中的[提示注入安全性](https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-injection.html)。

```
import { invokeModel } from '@aws-appsync/utils/ai'
export function request(ctx) {
  return invokeModel({
    modelId: 'amazon.titan-text-lite-v1',
    guardrailIdentifier: "zabcd12345678",
    guardrailVersion: "1",
    body: { inputText: `Summarize this text in less than 100 words. : \n<text>${ctx.stash.text ?? ctx.env.DEFAULT_TEXT}</text>` },
  })
}

export function response(ctx) {
  return ctx.result.results[0].outputText
}
```

下列範例使用具有跨區域推論描述檔 (us.anthropic.claude-3-5-haiku-20241022-v1：0) 的 `converse`函數。請參閱《Amazon Bedrock *使用者指南》，進一步了解 Amazon Bedrock* [推論描述檔的先決條件](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-prereq.html) 

**提醒**：您必須負責安全的應用程式開發和防止漏洞，例如提示注入。

```
import { converse } from '@aws-appsync/utils/ai'

export function request(ctx) {
  return converse({
    modelId: 'us.anthropic.claude-3-5-haiku-20241022-v1:0',
    system: [
      {
        text: `
You are a database assistant that provides SQL queries to retrieve data based on a natural language request. 
${ctx.args.explain ? 'Explain your answer' : 'Do not explain your answer'}.
Assume a database with the following tables and columns exists:

Customers:  
- customer_id (INT, PRIMARY KEY)  
- first_name (VARCHAR)  
- last_name (VARCHAR)  
- email (VARCHAR)  
- phone (VARCHAR)  
- address (VARCHAR)  
- city (VARCHAR)  
- state (VARCHAR)  
- zip_code (VARCHAR)  
  
Products:  
- product_id (INT, PRIMARY KEY)  
- product_name (VARCHAR)  
- description (TEXT)  
- category (VARCHAR)  
- price (DECIMAL)  
- stock_quantity (INT)  

Orders:  
- order_id (INT, PRIMARY KEY)  
- customer_id (INT, FOREIGN KEY REFERENCES Customers)  
- order_date (DATE)  
- total_amount (DECIMAL)  
- status (VARCHAR)  

Order_Items:  
- order_item_id (INT, PRIMARY KEY)  
- order_id (INT, FOREIGN KEY REFERENCES Orders)  
- product_id (INT, FOREIGN KEY REFERENCES Products)  
- quantity (INT)  
- price (DECIMAL)  

Reviews:  
- review_id (INT, PRIMARY KEY)  
- product_id (INT, FOREIGN KEY REFERENCES Products)  
- customer_id (INT, FOREIGN KEY REFERENCES Customers)  
- rating (INT)  
- comment (TEXT)  
- review_date (DATE)`,
      },
    ],
    messages: [
      {
        role: 'user',
        content: [{ text: `<request>${ctx.args.text}:</request>` }],
      },
    ],
  })
}

export function response(ctx) {
  return ctx.result.output.message.content[0].text
}
```

下列範例使用 `converse`建立結構化回應。請注意，我們使用環境變數做為資料庫結構描述參考，並設定護欄來協助防止攻擊。

```
import { converse } from '@aws-appsync/utils/ai'

export function request(ctx) {
  return generateObject({
    modelId: ctx.env.HAIKU3_5, // keep the model in an env variable
    prompt: ctx.args.query,
    shape: objectType(
      {
        sql: stringType('the sql query to execute as a javascript template string.'),
        parameters: objectType({}, 'the placeholder parameters for the query, if any.'),
      },
      'the sql query to execute along with the place holder parameters',
    ),
    system: [
      {
        text: `
You are a database assistant that provides SQL queries to retrieve data based on a natural language request. 

Assume a database with the following tables and columns exists:

${ctx.env.DB_SCHEMA_CUSTOMERS}
${ctx.env.DB_SCHEMA_ORDERS}
${ctx.env.DB_SCHEMA_ORDER_ITEMS}
${ctx.env.DB_SCHEMA_PRODUCTS}
${ctx.env.DB_SCHEMA_REVIEWS}`,
      },
    ],
    guardrailConfig: { guardrailIdentifier: 'iabc12345678', guardrailVersion: 'DRAFT' },
  })
}

export function response(ctx) {
  return toolReponse(ctx.result)
}

function generateObject(input) {
  const { modelId, prompt, shape, ...options } = input
  return converse({
    modelId,
    messages: [{ role: 'user', content: [{ text: prompt }] }],
    toolConfig: {
      toolChoice: { tool: { name: 'structured_tool' } },
      tools: [
        {
          toolSpec: {
            name: 'structured_tool',
            inputSchema: { json: shape },
          },
        },
      ],
    },
    ...options,
  })
}

function toolReponse(result) {
  return result.output.message.content[0].toolUse.input
}

function stringType(description) {
  const t = { type: 'string' /* STRING */ }
  if (description) {
    t.description = description
  }
  return t
}

function objectType(properties, description, required) {
  const t = { type: 'object' /* OBJECT */, properties }
  if (description) {
    t.description = description
  }
  if (required) {
    t.required = required
  }
  return t
}
```

根據結構描述：

```
type SQLResult {
    sql: String
    parameters: AWSJSON
}

type Query {
    db(text: String!): SQLResult
}
```

和查詢：

```
query db($text: String!) {
  db(text: $text) {
    parameters
    sql
  }
}
```

使用下列參數：

```
{
  "text":"What is my top selling product?"
}
```

會傳回下列回應：

```
{
  "data": {
    "assist": {
      "sql": "SELECT p.product_id, p.product_name, SUM(oi.quantity) as total_quantity_sold\nFROM Products p\nJOIN Order_Items oi ON p.product_id = oi.product_id\nGROUP BY p.product_id, p.product_name\nORDER BY total_quantity_sold DESC\nLIMIT 1;",
      "parameters": null
    }
  }
}
```

不過，使用此請求時：

```
{
  "text":"give me a query to retrieve sensitive information"
}
```

會傳回下列回應：

```
{
  "data": {
    "db": {
      "parameters": null,
      "sql": "SELECT null; -- I cannot and will not assist with retrieving sensitive private information"
    }
  }
}
```

若要進一步了解如何設定 Amazon Bedrock Guardrails，請參閱《*Amazon Bedrock 使用者指南*》中的[使用 Amazon Bedrock Guardrails 在模型中停止有害內容](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html)。

## 回應物件
<a name="response_object"></a>

來自 Amazon Bedrock 執行期調用的回應包含在內容的結果屬性 (context.result) 中。回應符合 Amazon Bedrock APIs指定的形狀。如需預期的調用結果形狀的詳細資訊，請參閱 [Amazon Bedrock 使用者指南](https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html)。

```
export function response(ctx) {
  return ctx.result
}
```

沒有套用至回應物件的必要欄位或形狀限制。不過，由於 GraphQL 是強式輸入，因此解析的回應必須符合預期的 GraphQL 類型。

## 長時間執行的叫用
<a name="long-running-invocations"></a>

許多組織目前使用 AWS AppSync 做為 AI 閘道，來建置採用 Amazon Bedrock 基礎模型技術的生成式 AI 應用程式。客戶使用 AWS AppSync 採用 WebSockets 技術的訂閱，從長時間執行的模型調用中傳回漸進式更新。這可讓它們實作非同步模式。

下圖示範如何實作此模式。在圖表中，會發生下列步驟。

1. 您的用戶端會啟動訂閱，以設定 WebSocket，並請求 AWS AppSync 觸發生成式 AI 調用。

1. AWS AppSync 在事件模式中呼叫您的 AWS Lambda 函數，並立即將回應傳回給用戶端。

1. 您的 Lambda 函數會在 Amazon Bedrock 上叫用模型。Lambda 函數可以使用同步 API，例如 `InvokeModel`或串流 API`InvokeModelWithResponseStream`，例如 ，以取得漸進式更新。

1. 當收到更新或呼叫完成時，Lambda 函數會透過觸發訂閱的 AWS AppSync API 變動傳送更新。

1. 訂閱事件會即時傳送，並由用戶端透過 WebSocket 接收。

![\[此圖表示範使用 AWS AppSync 訂閱從 Amazon Bedrock 模型傳回更新的工作流程。\]](http://docs.aws.amazon.com/zh_tw/appsync/latest/devguide/images/bedrock-workflow.png)


## 類型參考
<a name="type-reference-bedrock"></a>

```
export type BedrockMessage = {
  role: 'user' | 'assistant' | string;
  content: BedrockMessageContent[];
};

export type BedrockMessageContent =
  | { text: string }
  | { guardContent: BedrockGuardContent }
  | { toolResult: BedrockToolResult }
  | { toolUse: BedrockToolUse };

export type BedrockGuardContent = {
  text: BedrockGuardContentText;
};

export type BedrockGuardContentText = {
  text: string;
  qualifiers?: ('grounding_source' | 'query' | 'guard_content' | string)[];
};

export type BedrockToolResult = {
  content: BedrockToolResultContent[];
  toolUseId: string;
  status?: string;
};

export type BedrockToolResultContent = { json: any } | { text: string };

export type BedrockToolUse = {
  input: any;
  name: string;
  toolUseId: string;
};

export type ConversePayload = {
  modelId: string;
  body: any;
  guardrailIdentifier?: string;
  guardrailVersion?: string;
  guardrailTrace?: string;
};

export type BedrockGuardrailConfig = {
  guardrailIdentifier: string;
  guardrailVersion: string;
  trace: string;
};

export type BedrockInferenceConfig = {
  maxTokens?: number;
  temperature?: number;
  stopSequences?: string[];
  topP?: number;
};

export type BedrockPromptVariableValues = {
  text: string;
};

export type BedrockToolConfig = {
  tools: BedrockTool[];
  toolChoice?: BedrockToolChoice;
};

export type BedrockTool = {
  toolSpec: BedrockToolSpec;
};

export type BedrockToolSpec = {
  name: string;
  description?: string;
  inputSchema: BedrockInputSchema;
};

export type BedrockInputSchema = {
  json: any;
};

export type BedrockToolChoice =
  | { tool: BedrockSpecificToolChoice }
  | { auto: any }
  | { any: any };

export type BedrockSpecificToolChoice = {
  name: string;
};

export type BedrockSystemContent =
  | { guardContent: BedrockGuardContent }
  | { text: string };

export type BedrockConverseOutput = {
  message?: BedrockMessage;
};

export type BedrockConverseMetrics = {
  latencyMs: number;
};

export type BedrockTokenUsage = {
  inputTokens: number;
  outputTokens: number;
  totalTokens: number;
};

export type BedrockConverseTrace = {
  guardrail?: BedrockGuardrailTraceAsssessment;
};

export type BedrockGuardrailTraceAsssessment = {
  inputAssessment?: { [key: string]: BedrockGuardrailAssessment };
  modelOutput?: string[];
  outputAssessments?: { [key: string]: BedrockGuardrailAssessment };
};

export type BedrockGuardrailAssessment = {
  contentPolicy?: BedrockGuardrailContentPolicyAssessment;
  contextualGroundingPolicy?: BedrockGuardrailContextualGroundingPolicyAssessment;
  invocationMetrics?: BedrockGuardrailInvocationMetrics;
  sensitiveInformationPolicy?: BedrockGuardrailSensitiveInformationPolicyAssessment;
  topicPolicy?: BedrockGuardrailTopicPolicyAssessment;
  wordPolicy?: BedrockGuardrailWordPolicyAssessment;
};

export type BedrockGuardrailContentPolicyAssessment = {
  filters: BedrockGuardrailContentFilter[];
};

export type BedrockGuardrailContentFilter = {
  action: 'BLOCKED' | string;
  confidence: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | string;
  type:
    | 'INSULTS'
    | 'HATE'
    | 'SEXUAL'
    | 'VIOLENCE'
    | 'MISCONDUCT'
    | 'PROMPT_ATTACK'
    | string;
  filterStrength: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | string;
};

export type BedrockGuardrailContextualGroundingPolicyAssessment = {
  filters: BedrockGuardrailContextualGroundingFilter;
};

export type BedrockGuardrailContextualGroundingFilter = {
  action: 'BLOCKED' | 'NONE' | string;
  score: number;
  threshold: number;
  type: 'GROUNDING' | 'RELEVANCE' | string;
};

export type BedrockGuardrailInvocationMetrics = {
  guardrailCoverage?: BedrockGuardrailCoverage;
  guardrailProcessingLatency?: number;
  usage?: BedrockGuardrailUsage;
};

export type BedrockGuardrailCoverage = {
  textCharacters?: BedrockGuardrailTextCharactersCoverage;
};

export type BedrockGuardrailTextCharactersCoverage = {
  guarded?: number;
  total?: number;
};

export type BedrockGuardrailUsage = {
  contentPolicyUnits: number;
  contextualGroundingPolicyUnits: number;
  sensitiveInformationPolicyFreeUnits: number;
  sensitiveInformationPolicyUnits: number;
  topicPolicyUnits: number;
  wordPolicyUnits: number;
};

export type BedrockGuardrailSensitiveInformationPolicyAssessment = {
  piiEntities: BedrockGuardrailPiiEntityFilter[];
  regexes: BedrockGuardrailRegexFilter[];
};

export type BedrockGuardrailPiiEntityFilter = {
  action: 'BLOCKED' | 'ANONYMIZED' | string;
  match: string;
  type:
    | 'ADDRESS'
    | 'AGE'
    | 'AWS_ACCESS_KEY'
    | 'AWS_SECRET_KEY'
    | 'CA_HEALTH_NUMBER'
    | 'CA_SOCIAL_INSURANCE_NUMBER'
    | 'CREDIT_DEBIT_CARD_CVV'
    | 'CREDIT_DEBIT_CARD_EXPIRY'
    | 'CREDIT_DEBIT_CARD_NUMBER'
    | 'DRIVER_ID'
    | 'EMAIL'
    | 'INTERNATIONAL_BANK_ACCOUNT_NUMBER'
    | 'IP_ADDRESS'
    | 'LICENSE_PLATE'
    | 'MAC_ADDRESS'
    | 'NAME'
    | 'PASSWORD'
    | 'PHONE'
    | 'PIN'
    | 'SWIFT_CODE'
    | 'UK_NATIONAL_HEALTH_SERVICE_NUMBER'
    | 'UK_NATIONAL_INSURANCE_NUMBER'
    | 'UK_UNIQUE_TAXPAYER_REFERENCE_NUMBER'
    | 'URL'
    | 'USERNAME'
    | 'US_BANK_ACCOUNT_NUMBER'
    | 'US_BANK_ROUTING_NUMBER'
    | 'US_INDIVIDUAL_TAX_IDENTIFICATION_NUMBER'
    | 'US_PASSPORT_NUMBER'
    | 'US_SOCIAL_SECURITY_NUMBER'
    | 'VEHICLE_IDENTIFICATION_NUMBER'
    | string;
};

export type BedrockGuardrailRegexFilter = {
  action: 'BLOCKED' | 'ANONYMIZED' | string;
  match?: string;
  name?: string;
  regex?: string;
};

export type BedrockGuardrailTopicPolicyAssessment = {
  topics: BedrockGuardrailTopic[];
};

export type BedrockGuardrailTopic = {
  action: 'BLOCKED' | string;
  name: string;
  type: 'DENY' | string;
};

export type BedrockGuardrailWordPolicyAssessment = {
  customWords: BedrockGuardrailCustomWord[];
  managedWordLists: BedrockGuardrailManagedWord[];
};

export type BedrockGuardrailCustomWord = {
  action: 'BLOCKED' | string;
  match: string;
};

export type BedrockGuardrailManagedWord = {
  action: 'BLOCKED' | string;
  match: string;
  type: 'PROFANITY' | string;
};
```