

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

# リゾルバーと関数のAWS AppSync JavaScript ランタイム機能
<a name="resolver-util-reference-js"></a>

`APPSYNC_JS` ランタイム環境には [ECMAScript (](https://262.ecma-international.org/6.0/)ES) バージョン 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) - 変数には、データの操作を容易にする一般的なユーティリティメソッドが含まれています。特に指定されていない限り、すべてのユーティリティでは 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 に基づいています。詳細については、[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 ]

次のタイプの BGP がサポートされています。
+ 数字
+ 文字列
+ ブール値
+ objects
+ 配列
+ 関数

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

次のような演算子がサポートされています。
+ 標準の数学演算子 (`+`、`-`、`/`、`%`、`*` など)
+ Null 合体演算子 (`??`) 
+ オプションのチェーニング (`?.`)
+ ビット演算子
+ `void` および `typeof` 演算子
+ スプレッド演算子 (`...`)

以下は、サポートされていない演算子です。
+ 単項演算子 (`++`、`--`、および `~`) 
+ `in` operator
**注記**  
`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 REST パラメータ構文はサポートされています。

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

関数は Strict モードで動作するため、関数コードに `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>

以下の ES 5.1 グローバル関数がサポートされています。

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

次の 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 ]
+ `apply`、`bind` `call` メソッドはサポートされていません。
+ 関数コンストラクタはサポートされていません。
+ 関数を引数として渡すことはサポートされていません。
+ 再帰的な関数呼び出しはサポートされていません。

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

以下の JSON メソッドがサポートされています。
+ `JSON.parse()`
**注記**  
解析された文字列が有効な JSON でない場合は、空白の文字列を返します。
+ `JSON.stringify()`

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

非同期プロセスはサポートされておらず、Promise もサポートされていません。

**注記**  
ネットワークおよびファイルシステムへのアクセスは、 `APPSYNC_JS`ランタイム内ではサポートされていません AWS AppSync。 は、 AWS AppSync リゾルバーまたは AWS AppSync 関数によって行われたリクエストに基づいて、すべての I/O オペレーション AWS AppSync を処理します。

------

## Globals
<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()`**  
長さ 27 の文字列としてエンコードされた、ランダムに生成された 128 ビットの KSUID (K ソート可能な固有識別子) base62 を返します。

## エラー utils
<a name="utility-helpers-in-error-js"></a>

### エラー utils リスト
<a name="utility-helpers-in-error-list-js"></a>

 **`util.error(String, String?, Object?, Object?)`**  
カスタムエラーをスローします。これは、テンプレートがリクエストまたは呼び出し結果でエラーを検出した場合に、リクエストまたはレスポンスのマッピングテンプレートで使用できます。また、`errorType` フィールド、`data` フィールド、および `errorInfo` フィールドを指定できます。`data` の値は、GraphQL レスポンスの `errors` 内の該当する `error` ブロックに追加されます。  
`data` はクエリ選択セットに基づいてフィルタリングされます。`errorInfo` の値は、GraphQL レスポンスの `errors` 内の該当する `error` ブロックに追加されます。  
`errorInfo` はクエリ選択セットに基づいてフィルタリング**されません**。

 **`util.appendError(String, String?, Object?, Object?)`**  
カスタムエラーを追加します。これは、テンプレートがリクエストまたは呼び出し結果でエラーを検出した場合に、リクエストまたはレスポンスのマッピングテンプレートで使用できます。また、`errorType` フィールド、`data` フィールド、および `errorInfo` フィールドを指定できます。`util.error(String, String?, Object?, Object?)` とは異なり、テンプレートの評価は中断されないため、データを呼び出し元に返すことができます。`data` の値は、GraphQL レスポンスの `errors` 内の該当する `error` ブロックに追加されます。  
`data` はクエリ選択セットに基づいてフィルタリングされます。`errorInfo` の値は、GraphQL レスポンスの `errors` 内の該当する `error` ブロックに追加されます。  
`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`**  
最初の引数で指定されたパターンが、2 番目の引数で指定されたデータと一致する場合は true を返します。パターンは正規表現である必要があります (例: `util.matches("a*b", "aaaaab")`)。この機能は Java の Pattern に基づいています。詳細については、[Pattern](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html) を参照してください。

 **`util.authType()`**   
リクエストで使用されているマルチ認可タイプを表す文字列型 (String) の値を返します。「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)`**  
入力文字列を JavasScript のエスケープした文字列として返します。

## リゾルバー認可 utils
<a name="utility-helpers-in-resolver-auth-js"></a>

### リゾルバー認可 utils リスト
<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)」を参照してください。
DynamoDB に [GetItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-getitem) リクエストを行うための `DynamoDBGetItemRequest` オブジェクトを生成します。  

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

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

 **`put<T>(payload): DynamoDBPutItemRequest`**  
DynamoDB に [PutItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem) リクエストを行うための `DynamoDBPutItemRequest` オブジェクトを生成します。  

```
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`**  
DynamoDB に [DeleteItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-deleteitem) リクエストを行うための `DynamoDBDeleteItemRequest` オブジェクトを生成します。  

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

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

**`scan<T>(payload): DynamoDBScanRequest`**  
DynamoDB に [Scan](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan) リクエストを行うための`DynamoDBScanRequest`を生成します。  

```
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`**  
[Sync](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-sync) リクエストを行う `DynamoDBSyncRequest` オブジェクトを生成します。リクエストは、前回のクエリ (デルタ更新) 以降に変更されたデータのみを受け取ります。リクエストは、バージョン管理された 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`**  
DynamoDB に [UpdateItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-updateitem) リクエストを行うための `DynamoDBUpdateItemRequest` オブジェクトを生成します。

### オペレーション
<a name="built-in-ddb-modules-operations"></a>

オペレーションヘルパーを使用すると、更新中にデータの一部に対して特定のアクションを実行できます。はじめに、`@aws-appsync/utils/dynamodb` から `operations` をインポートしてください。

```
// 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 の既存のリストにペイロードを追加するヘルパー関数。  
**例**  
更新中に新しく追加されたフレンド ID (`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 の既存のリストの前に追加するヘルパー関数。  
**例**  
更新時に、新しく追加されたフレンド ID (`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`) のスコープで、この例では `friendsIds` を使用してリスト (`updateListItem`) の 2 番目の項目 (index: `1`、new ID:`102`) と 3 番目の項目 (index: `2`、new ID:`112`) の ID 値を更新しました。  

```
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>` (必須)

  Put が実行される 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` にリストされている属性のみを返します。この戻り値は、`AttributesToGet` の値を指定せずに `ProjectionExpression` を指定することと同じです。
+ `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 操作を実行するときに使用するベーステーブルのパーティションキー。このフィールドにより、テーブルがカスタムパーティションキーを使用している場合に Sync 操作を実行できます。
+ `deltaIndexName?: string` (オプション)

  Sync 操作に使用されるインデックス。このインデックスは、テーブルがカスタムパーティションキーを使用する場合に、デルタストアテーブル全体で Sync 操作を有効にするために必要です。Sync オペレーションは GSI (`gsi_ds_pk` と `gsi_ds_sk` で作成) で実行されます。
+ `filter?: DynamoDBFilterObject<T> | null` (オプション)

  テーブルから結果を取得した後に結果に適用するオプションのフィルター。
+ `lastSync?: number` (オプション)

  最後に成功した Sync オペレーションが開始されたエポックミリ秒単位の時刻。指定すると、`lastSync` 以降に変更された項目のみが返されます。このフィールドはオプションです。最初の Sync オペレーションからすべてのページを取得した後にのみ入力する必要があります。省略すると、ベーステーブルの結果が返されます。それ以外の場合は、差分テーブルの結果が返されます。
+ `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**

`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
    }));
}
```

**ORDER BY**

結果は `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 } }
        ]}
    }));
}
```

以下の演算子を使用して、値を比較することもできます。


| 
| 
| 演算子 | 説明 | 可能な値型 | 
| --- |--- |--- |
| 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` の `name` を `3` の `id` 値で更新したいのですが、これは `2000` 年以降にそれら (`known_since`) がわかっている場合に限ります。

```
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)
}
```

条件にチェックを追加して、`3` と等しいプライマリキー `id` を持つ行だけが更新されるようにすることができます。同様に、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>

ステートメントで使用する正しいオブジェクト型に関して、さらに特異度が必要となる場合もあるでしょう。指定された型ヒントを使用してパラメータのタイプを指定できます。 は Data API [と同じ型ヒント](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html#rdsdtataservice-Type-SqlParameter-typeHint) AWS AppSync をサポートします。モジュールの `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` を「END」に `skipTo` 設定すると、パイプラインの実行はスキップされ、パイプラインリゾルバーレスポンスハンドラーは即座に呼び出されます。
+ `returnOptions` を「NEXT」に `skipTo` 設定すると、関数の実行はスキップされ、次のパイプラインハンドラーが呼び出されます。
**例**  

```
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` 変数には、タイムスタンプの生成、日時形式間の変換、および日時文字列の解析に役立つ日時メソッドが含まれています。日時形式の構文は Java の DateTimeFormatter に基づいています。詳細については、[DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) を参照してください。

## 日時 utils リスト
<a name="utility-helpers-in-time-list-js"></a>

 **`util.time.nowISO8601()`**  
[ISO 8601 形式](https://en.wikipedia.org/wiki/ISO_8601)の UTC の文字列型表現を返します。

 **`util.time.nowEpochSeconds()`**  
エポック (1970-01-01T00:00:00Z) から現在までの秒数を返します。

 **`util.time.nowEpochMilliSeconds()`**  
エポック (1970-01-01T00:00:00Z) から現在までのミリ秒数を返します。

 **`util.time.nowFormatted(String)`**  
文字列型の入力引数で指定された形式を使用して、UTC での現在のタイムスタンプを返します。

 **`util.time.nowFormatted(String, String)`**  
文字列型の入力引数で指定された形式とタイムゾーンを使用して、そのタイムゾーンでの現在のタイムスタンプを返します。

 **`util.time.parseFormattedToEpochMilliSeconds(String, String)`**  
文字列として、タイムゾーンを含む形式で渡されたタイムスタンプを解析し、エポックからのミリ秒単位のタイムスタンプを返します。

 **`util.time.parseFormattedToEpochMilliSeconds(String, String, String)`**  
文字列型として渡されたタイムスタンプ、形式、およびタイムゾーンを解析し、エポックからのミリ秒単位のタイムスタンプを返します。

 **`util.time.parseISO8601ToEpochMilliSeconds(String)`**  
文字列型として渡された ISO8601 形式のタイムスタンプを解析し、エポックからのミリ秒単位のタイムスタンプを返します。

 **`util.time.epochMilliSecondsToSeconds(long)`**  
エポックからのミリ秒単位のタイムスタンプを、エポックからの秒単位のタイムスタンプに変換します。

 **`util.time.epochMilliSecondsToISO8601(long)`**  
エポックからのミリ秒単位のタイムスタンプを、ISO8601 形式のタイムスタンプに変換します。

 **`util.time.epochMilliSecondsToFormatted(long, String)`**  
long として渡されたエポックからのミリ秒単位のタイムスタンプを、文字列型で指定された形式に合わせて UTC でのタイムスタンプに変換します。

 **`util.time.epochMilliSecondsToFormatted(long, String, String)`**  
long として渡されたエポックからのミリ秒単位のタイムスタンプを、文字列型で指定された形式とタイムゾーンに合わせて、そのタイムゾーンでのタイムスタンプに変換します。

# 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 utils リスト
<a name="utility-helpers-in-toDynamoDB-list-js"></a>

 **`util.dynamodb.toDynamoDB(Object)`**   
入力されたオブジェクトを適切な DynamoDB 表現形式に変換する DynamoDB 用の一般的なオブジェクト変換ツールです。このツールは、一部の型の表現方法に関して融通が利きません。例えば、セット型 ("SS"、"NS"、"BS") ではなくリスト型 ("L") が使用されます。これは、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()`**  
null を DynamoDB の 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 形式に変換されます。このツールは、一部のネステッドオブジェクトの表現方法に関して融通が利きません。例えば、セット型 ("SS"、"NS"、"BS") ではなくリスト型 ("L") が使用されます。これは、DynamoDB 属性値を記述するオブジェクトを返します。  

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

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

### toMap utils リスト
<a name="utility-helpers-in-toMap-list-js"></a>

 **`util.dynamodb.toMap(Map)`**  
マップを DynamoDB のマップ形式に変換します。マップ内の各値も、該当する DynamoDB 形式に変換されます。このツールは、一部のネステッドオブジェクトの表現方法に関して融通が利きません。例えば、セット型 ("SS"、"NS"、"BS") ではなくリスト型 ("L") が使用されます。これは、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 形式に変換して、マップのコピーを作成します。このツールは、一部のネステッドオブジェクトの表現方法に関して融通が利きません。例えば、セット型 ("SS"、"NS"、"BS") ではなくリスト型 ("L") が使用されます。  

```
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 の属性値の内容のみを返します。例えば、次の 2 つのステートメントはまったく同じです。  

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

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

### S3Object utils リスト
<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`) を含むカスタムヘッダーを 1 つ追加します。以下の制限が適用されます。  
+ `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 操作ごとに 1 回定義する必要があります。ただし、同じ名前のカスタムヘッダーを複数回定義すると、最新の定義がレスポンスに表示されます。名前に関係なく、すべてのヘッダーがヘッダーサイズの上限に含まれます。
+ 名前 `(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` には、Amazon DynamoDB フィルター処理などの、データソースに対する複雑なオペレーションの実行を容易にするヘルパーメソッドが含まれています。

## 変換ヘルパー utils リスト
<a name="transformation-helpers-in-utils-transform-js-list"></a>

**`util.transform.toDynamoDBFilterExpression(filterObject: DynamoDBFilterObject) : string`**  
Amazon 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)」を参照してください。  
パラメータと return ステートメントは以下のとおりです。  
*パラメータ*  
+ `objFilter`: `SubscriptionFilterObject`

  `SubscriptionFilter`式オブジェクトに変換された `Map` 入力オブジェクト。
+ `ignoredFields`: `SubscriptionFilterExcludeKeysType` (オプション)

  最初のオブジェクトのフィールド名は無視されます。
+ `rules`: `SubscriptionFilterRuleObject` (オプション)

  `SubscriptionFilter` 式オブジェクトを作成する際に含める、厳格なルールが適用された `Map` 入力オブジェクト。これらの厳格なルールは `SubscriptionFilter` 式オブジェクトに含まれるため、少なくとも 1 つのルールが満たされてサブスクリプションフィルターを通過することになります。
*レスポンス*  
戻り値は `[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)」を参照してください。  
1 番目の引数は、`SubscriptionFilter` 式オブジェクトに変換される `Map` 入力オブジェクトです。2 番目の引数は、`SubscriptionFilter` 式オブジェクトを作成する際に 1 番目の `Map` 入力オブジェクトでは無視されるフィールド名の `List` です。

**`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` オブジェクトです。
+ フィールド名
+ "and"
+ "or"

フィールド名をキーとする場合、これらのフィールドのエントリの条件は `"operator" : "value"` という形式になります。

次の例では、`Map` にエントリを追加する方法を示します。

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

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

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

フィールドに 2 つ以上の条件が設定されている場合、これらの条件はすべて OR 演算を使用するものとみなされます。

入力 `Map` には「and」と「or」をキーとして使用することもできます。つまり、その中のすべてのエントリは、キーに応じて AND または OR ロジックを使用して結合する必要があります。キー値「and」と「or」には条件の配列が必要です。

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

「and」と「or」はネストできることに注意してください。つまり、「and/or」を別の「and/or」ブロック内にネストしてもかまいません。ただし、これは単純なフィールドでは機能しません。

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

次の例は、`util.transform.toSubscriptionFilter(Map) : Map`を使用して*引数 1* を入力したものです。

**入力**

引数 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` 式オブジェクトを作成するときに入力 `Map` (引数 1) で考慮してはいけないフィールド名の `List` が含まれています。`List` は空になることもあります。

次の例は、`util.transform.toSubscriptionFilter(Map, List) : Map` を使用した引数 1 と引数 2 の入力を示しています。

**入力**

引数 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` オブジェクトです (「and」や「or」は使用できません)。フィールド名がキーの場合、これらのフィールドの条件は `"operator" : "value"` という形式のエントリになります。引数 1 とは異なり、引数 3 では同じキーに複数の条件を設定できません。さらに、引数 3 には「and」や「or」句がないため、ネストも必要ありません。

引数 3 は厳密な規則のリストを表し、これらの条件の**少なくとも 1 つ**が満たされてフィルタを通過するように `SubscriptionFilter` 式オブジェクトに追加されます。

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

次の例は、`util.transform.toSubscriptionFilter(Map, List, Map) : Map` を使用した*引数 1*、*引数 2*、*引数 3* の入力を示しています。

**入力**

引数 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)`**  
NFC、NFD、NFKC、または NFKD の 4 つのユニコード正規化形式のいずれかを使用して文字列を正規化します。最初の引数は正規化する文字列です。2 番目の引数は、正規化プロセスに使用する正規化タイプを指定する「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 サーバー側のキャッシュから項目を削除します。最初の引数は型名です。2 番目の引数はフィールド名です。3 番目の引数は、キャッシュキー値を指定するキーと値のペア項目を含むオブジェクトです。オブジェクト内の項目は、キャッシュされたリゾルバーの `cachingKey` のキャッシュキーと同じ順序で配置する必要があります。キャッシュの詳細については、「[キャッシング動作](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html#caching-behavior)」を参照してください。  
**例 1:**  
この例では、呼び出されたキャッシュキー `context.arguments.semester` が使用されたリゾルバー `Query.allClasses` に対してキャッシュされた項目がエビクションされています。ミューテーションが呼び出されてリゾルバーが実行され、エントリが正常にクリアされると、レスポンスには拡張子オブジェクトに、削除されたエントリの数を示す `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*」セクションを参照してください)。  
この拡張関数はミューテーションリゾルバーのレスポンスマッピングテンプレートでのみ使用できます。  
1 つのリクエストで使用できるユニークな `extensions.invalidateSubscriptions()` メソッド呼び出しは 5 つまでです。この制限を超えた場合、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"]
                }
           ]
           
        }
    ]
}
```

各フィルターには次の 3 つの属性があります。
+ `fieldName` – GraphQL スキーマフィールド。
+ `operator` – オペレータータイプ。
+ `value` – サブスクリプション通知 `fieldName` 値と比較する値。

以下は、これらの属性の割り当ての例です。

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

## 引数: invalidationJsonObject
<a name="extensions-invalidationJsonObject-js"></a>

`invalidationJsonObject` では以下が定義されます。
+ `subscriptionField` – 無効にする GraphQL スキーマのサブスクリプション。`subscriptionField`で文字列として定義されている 1 つのサブスクリプションは無効とみなされます。
+ `payload` — 無効化フィルターがその値に対して `true` と評価された場合に、サブスクリプションを無効化するための入力として使用されるキーと値のペアリスト。

  以下の例では、サブスクリプションリゾルバーで定義された無効化フィルターが `payload` 値に対して `true` と評価されたとき、`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` に似ています。これは、XML レスポンスを HTTP オブジェクトから JSON に直接変換し、返す場合に便利です。オプションの boolean パラメータを設定して、JSON を文字列でエンコードするかどうかを決定できます。