

AWS SDK for JavaScript v2 はサポート終了となりました。[AWS SDK for JavaScript v3](https://docs.aws.amazon.com//sdk-for-javascript/v3/developer-guide/) に移行することをお勧めします。その他の詳細、移行方法については、こちらの[発表内容](https://aws.amazon.com/blogs//developer/announcing-end-of-support-for-aws-sdk-for-javascript-v2/)を参照してください。

# SDK for JavaScript でのサービスの操作
<a name="working-with-services"></a>

AWS SDK for JavaScript は、クライアントクラスのコレクションを通じて、サポート対象となるサービスへのアクセスを提供します。これらのクライアントクラスから、一般に*サービスオブジェクト*と呼ばれるサービスインターフェイスオブジェクトが作成されます。サポートされている各 AWS サービスには、サービス機能とリソースを使用するための低レベル API を提供するクライアントクラスが 1 つ以上あります。例えば、Amazon DynamoDB API は、`AWS.DynamoDB` クラスから利用できます。

SDK for JavaScript を通じて公開されるサービスは、リクエストレスポンスのパターンに従って、呼び出し元のアプリケーションとメッセージを交換します。このパターンでは、サービスを呼び出すコードが HTTP/HTTPS リクエストをそのサービスのエンドポイントに送信します。リクエストには、呼び出されている特定の機能を正常に呼び出すために必要なパラメータが含まれています。呼び出されたサービスは、リクエスタに返されるレスポンスを生成します。オペレーションが成功した場合、レスポンスにはデータが含まれています。オペレーションが失敗した場合は、エラー情報が含まれています。

![\[AWS のリクエストレスポンスサービスパターン。\]](http://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/images/request-response.png)


AWS サービスの呼び出しには、試行された再試行を含め、サービスオブジェクトに対するオペレーションのリクエストとレスポンスのライフサイクル全体が含まれています。リクエストは、`AWS.Request` オブジェクトによって SDK にカプセル化されます。レスポンスは、`AWS.Response` オブジェクトによって SDK にカプセル化されています。このオブジェクトは、コールバック関数や JavaScript promise などのいくつかの手法の 1 つを通してリクエスタに提供されます。

**Topics**
+ [サービスオブジェクトの作成と呼び出し](creating-and-calling-service-objects.md)
+ [AWS SDK for JavaScript 呼び出しのログ記録](logging-sdk-calls.md)
+ [非同期的なサービスの呼び出し](calling-services-asynchronously.md)
+ [レスポンスオブジェクトの使用](the-response-object.md)
+ [JSON の使用](working-with-json.md)
+ [AWS SDK for JavaScript v2 での再試行戦略](retry-strategy.md)

# サービスオブジェクトの作成と呼び出し
<a name="creating-and-calling-service-objects"></a>

JavaScript API は、利用可能なほとんどの AWS のサービスをサポートしています。JavaScript API の各サービスクラスは、そのサービス内のすべての API 呼び出しへのアクセスを提供します。JavaScript API のサービスクラス、オペレーション、およびパラメータの詳細については、「[API リファレンス](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/index.html)」を参照してください。

Node.js で SDK を使用する場合、`require` を使用して SDK パッケージをアプリケーションに追加します。これにより、現在のすべてのサービスがサポートされます。

```
var AWS = require('aws-sdk');
```

ブラウザの JavaScript で SDK を使用する場合、AWS がホストする SDK パッケージを使用して、SDK パッケージをブラウザスクリプトにロードします。SDK パッケージをロードするには、次の `<script>` 要素を追加します。

```
<script src="https://sdk.amazonaws.com/js/aws-sdk-SDK_VERSION_NUMBER.min.js"></script>
```

最新の SDK\$1VERSION\$1NUMBER を確認するには、[AWS SDK for JavaScriptAPI リファレンスガイド](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/)で SDK for JavaScript の API リファレンスを参照してください。

デフォルトのホスティングされた SDK パッケージは、利用可能な AWS のサービスのサブセットをサポートしています。ブラウザ用のホスティングされた SDK パッケージのデフォルトサービスリストについては、API リファレンスの「[サポートされるサービス](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/#Supported_Services)」を参照してください。CORS セキュリティチェックが無効になっている場合は、SDK を他のサービスで使用することができます。この場合、カスタムバージョンの SDK を構築して、必要な追加のサービスを含めることができます。SDK のカスタムバージョン構築の詳細については、「[ブラウザ用 SDK の構築](building-sdk-for-browsers.md)」を参照してください。

## 個々のサービスを要求する
<a name="requiring-individual-services"></a>

前述のように SDK for JavaScript を要求すると、コードに SDK 全体が含まれます。または、コードで使用される個々のサービスのみを要求するように選択できます。Amazon S3 サービスオブジェクトの作成に使用される以下のコードを検討してください。

```
// Import the AWS SDK
var AWS = require('aws-sdk');

// Set credentials and Region
// This can also be done directly on the service client
AWS.config.update({region: 'us-west-1', credentials: {YOUR_CREDENTIALS}});

var s3 = new AWS.S3({apiVersion: '2006-03-01'});
```

前の例では、`require` 関数は SDK 全体を指定します。Amazon S3 サービスに必要な SDK の部分だけが含まれている場合、ネットワーク上で転送するコードの量、およびコードのメモリオーバーヘッドはかなり少なくなります。個々のサービスを要求するには、すべて小文字のサービスコンストラクタを含めて、示されているように `require` 関数を呼び出します。

```
require('aws-sdk/clients/SERVICE');
```

SDK の Amazon S3 部分のみが含まれている場合、前の Amazon S3 サービスオブジェクトを作成するためのコードは次のようになります。

```
// Import the Amazon S3 service client
var S3 = require('aws-sdk/clients/s3');
 
// Set credentials and Region
var s3 = new S3({
    apiVersion: '2006-03-01',
    region: 'us-west-1', 
    credentials: {YOUR_CREDENTIALS}
  });
```

すべてのサービスをアタッチしなくても、グローバル AWS の名前空間にアクセスできます。

```
require('aws-sdk/global');
```

この手法は、同じ設定を複数の個々のサービスに適用する場合に便利です (たとえば、すべてのサービスに同じ認証情報を提供するなど)。個々のサービスを要求することで、Node.js でのロード時間とメモリ消費量が削減されます。個々のサービスの要求を Browserify や webpack などのバンドルツールと一緒に実行すると、SDK は完全なサイズの数分の 1 になります。これは、IoT デバイスや Lambda 関数など、メモリやディスク容量に制約のある環境で役立ちます。

## サービスオブジェクトの作成
<a name="creating-service-objects"></a>

JavaScript API を介してサービス機能にアクセスするには、まず *サービスオブジェクト*を作成します。このサービスオブジェクトを通じて、基盤となるクライアントクラスが提供する一連の機能にアクセスします。通常、各サービスにつき 1 つのクライアントクラスが用意されています。ただし、一部のサービスでは、複数のクライアントクラス間でサービス機能へのアクセスを分割しています。

機能を使用するには、その機能へのアクセスを提供するクラスのインスタンスを作成する必要があります。次の例は、`AWS.DynamoDB` クライアントクラスからの DynamoDB 用のサービスオブジェクトの作成を示しています。

```
var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
```

デフォルトで、サービスオブジェクトにはグローバル設定が構成されます。この設定は、SDK の設定にも使用されます。ただし、そのサービスオブジェクトに固有のランタイム設定データを使用してサービスオブジェクトを設定することができます。グローバル設定を適用した後に、サービス固有の設定データが適用されます。

次の例では、Amazon EC2 サービスオブジェクトが特定のリージョンの設定で作成されますが、それ以外の場合にはグローバル設定が使用されます。

```
var ec2 = new AWS.EC2({region: 'us-west-2', apiVersion: '2014-10-01'});
```

個々のサービスオブジェクトに適用されるサービス固有の設定をサポートすることに加えて、指定されたクラスの、新しく作成されたすべてのサービスオブジェクトに対してサービス固有の設定を適用することもできます。例えば、Amazon EC2 クラスから作成されたすべてのサービスオブジェクトが米国西部 (オレゴン)(`us-west-2`) リージョンを使用するように設定するには、`AWS.config` グローバル設定オブジェクトに以下を追加します。

```
AWS.config.ec2 = {region: 'us-west-2', apiVersion: '2016-04-01'};
```

## サービスオブジェクトの API バージョンのロック
<a name="locking-api-version-of-service-objects"></a>

オブジェクト作成時に `apiVersion` オプションを指定することで、サービスオブジェクトを特定のサービスの API バージョンにロックすることができます。次の例では、特定の API バージョンにロックされている DynamoDB サービスオブジェクトが作成されます。

```
var dynamodb = new AWS.DynamoDB({apiVersion: '2011-12-05'});
```

サービスオブジェクトの API バージョンのロックに関する詳細については、「[API バージョンのロック](locking-api-versions.md)」を参照してください。

## サービスオブジェクトパラメータの指定
<a name="specifying-service-object-parameters"></a>

サービスオブジェクトのメソッドを呼び出す場合、API の必要に応じて JSON でパラメータを渡します。例えば、Amazon S3 では、指定されたバケットとキーのオブジェクトを取得するために、`getObject` メソッドに以下のパラメータを渡します。JSON パラメータを渡す詳細については、「[JSON の使用](working-with-json.md)」を参照してください。

```
s3.getObject({Bucket: 'bucketName', Key: 'keyName'});
```

Amazon S3 パラメータの詳細については、API リファレンスの「[https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html)」を参照してください。

さらに、サービスオブジェクト作成時に、`params` パラメータを使用して個々のパラメータに値をバインドすることができます。サービスオブジェクトの `params` パラメータの値は、サービスオブジェクトによって定義された 1 つ以上のパラメータ値を指定するマップです。次の例は、Amazon S3 サービスオブジェクトの `Bucket` パラメータが `amzn-s3-demo-bucket` という名前のバケットにバインドされていることを示しています。

```
var s3bucket = new AWS.S3({params: {Bucket: 'amzn-s3-demo-bucket'}, apiVersion: '2006-03-01' });
```

サービスオブジェクトをバケットにバインドすることで、`s3bucket` サービスオブジェクトは `amzn-s3-demo-bucket` パラメータ値をデフォルト値として扱い、以降のオペレーションで指定する必要がなくなります。パラメータ値が適用できないオペレーションにオブジェクトを使用すると、バインドされたパラメータ値はすべて無視されます。新しい値を指定してサービスオブジェクトを呼び出すときに、このバインドされたパラメータをオーバーライドできます。

```
var s3bucket = new AWS.S3({ params: {Bucket: 'amzn-s3-demo-bucket'}, apiVersion: '2006-03-01' });
s3bucket.getObject({Key: 'keyName'});
// ...
s3bucket.getObject({Bucket: 'amzn-s3-demo-bucket3', Key: 'keyOtherName'});
```

各メソッドで利用可能なパラメータに関する詳細は、API リファレンスにあります。

# AWS SDK for JavaScript 呼び出しのログ記録
<a name="logging-sdk-calls"></a>

AWS SDK for JavaScript には組み込みロガーが実装されているため、DK for JavaScript で行った API 呼び出しをログに記録できます。

ロガーをオンにしてコンソールにログエントリを出力するには、コードに次のステートメントを追加します。

```
AWS.config.logger = console;
```

ログ出力の例を次に示します。

```
[AWS s3 200 0.185s 0 retries] createMultipartUpload({ Bucket: 'amzn-s3-demo-logging-bucket', Key: 'issues_1704' })
```

## サードパーティー製のロガーの使用
<a name="third-party-logger"></a>

ログファイルまたはサーバーに書き込むオペレーションが `log()`、または `write()` の場合、サードパーティーのロガーを使用することもできます。SDK for JavaScript で使用する前に、指示に従ってカスタムロガーをインストールしてセットアップする必要があります。

ブラウザスクリプトと Node.js のどちらでも使用できるそのようなロガーの 1 つは、logplease です。Node.js で、logplease を設定してログファイルにログエントリを書き込むことができます。webpack でも使用できます。

サードパーティーのロガーを使用する場合は、`AWS.Config.logger` にロガーを割り当てる前にすべてのオプションを設定します。たとえば、以下は外部ログファイルを指定して、logplease のログレベルを設定します。

```
// Require AWS Node.js SDK
const AWS = require('aws-sdk')
// Require logplease
const logplease = require('logplease');
// Set external log file option
logplease.setLogfile('debug.log');
// Set log level
logplease.setLogLevel('DEBUG');
// Create logger
const logger = logplease.create('logger name');
// Assign logger to SDK
AWS.config.logger = logger;
```

logplease の詳細については、GitHub の「[シンプルな JavaScript ロガー logplease](https://github.com/haadcode/logplease)」を参照してください。

# 非同期的なサービスの呼び出し
<a name="calling-services-asynchronously"></a>

SDK を介して行われるリクエストはすべて非同期です。ブラウザスクリプトを作成するときに、この点に注意してください。通常、ウェブブラウザで実行されている JavaScript には、1 つの実行スレッドしかありません。AWS サービスへの非同期呼び出しを行った後、ブラウザスクリプトは実行を継続し、その過程で、非同期の結果が戻る前に、その結果に依存するコードの実行を試みる可能性があります。

AWS サービスへの非同期呼び出しにはそれらの呼び出しの管理が含まれているため、データが利用可能になる前にコードがデータの使用を試みることはありません。このセクションのトピックでは、非同期呼び出し管理の必要性を説明し、それらを管理するために使用できるさまざまな手法について詳しく説明します。

**Topics**
+ [非同期呼び出しの管理](making-asynchronous-calls.md)
+ [無名コールバック関数の使用](using-a-callback-function.md)
+ [リクエストオブジェクトのイベントリスナーの使用](using-a-response-event-handler.md)
+ [async/await の使用](using-async-await.md)
+ [JavaScript Promises の使用](using-promises.md)

# 非同期呼び出しの管理
<a name="making-asynchronous-calls"></a>

たとえば、e コマースウェブサイトのホームページは、リピート顧客がサインインするようにします。サインインする顧客にとっての利点の 1 つは、サインイン後に、顧客の特定の好みに合わせてサイトがカスタマイズされることです。これを実現するには、以下のことが必要です。

1. 顧客はログインし、サインイン認証情報で認証を受ける必要があります。

1. 顧客の好みは顧客データベースからリクエストされます。

1. データベースは、ページがロードされる前に、サイトのカスタマイズに使用される顧客の好みを提供します。

これらのタスクが同期的に実行される場合、それぞれの処理が完了してからでなければ、次が開始できません。データベースから顧客の好みが返されるまで、ウェブページはロードを終了することができません。しかし、データベースクエリがサーバーに送信された後、ネットワークのボトルネック、異常に高いデータベーストラフィック、またはモバイルデバイスの接続不良のために、顧客データの受信が遅れたり、失敗することさえあります。

このような状況でウェブサイトがフリーズしないようにするため、データベースを非同期的に呼び出します。データベース呼び出しが実行され、非同期リクエストが送信された後も、コードは想定どおりに継続して実行されます。非同期呼び出しのレスポンスを適切に管理しないと、コードは、データベースから返されると想定される情報がまだ利用できないときに、そのデータを使用しようとする可能性があります。

![\[同期実行と非同期実行の違いを表示。\]](http://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/images/async-vs-sync.png)


# 無名コールバック関数の使用
<a name="using-a-callback-function"></a>

`AWS.Request` オブジェクトを作成する各サービスオブジェクトメソッドは、最後のパラメータとして無名コールバック関数を使用できます。このコールバック関数の署名は次のとおりです。

```
function(error, data) {
    // callback handling code
}
```

このコールバック関数が実行されるのは、成功したレスポンスまたはエラーデータが返されたときです。メソッドの呼び出しに成功すると、レスポンスの内容は `data` パラメータでコールバック関数に利用可能になります。呼び出しが成功しない場合、エラーの詳細は `error` パラメータに記載されます。

通常、コールバック関数内のコードはエラーをテストし、エラーが返された場合はそれを処理します。エラーが返されない場合、コードは `data` パラメータからレスポンス内のデータを取得します。コールバック関数の基本的な形式は次の例のようになります。

```
function(error, data) {
    if (error) {
        // error handling code
        console.log(error);
    } else {
        // data handling code
        console.log(data);
    }
}
```

前の例では、エラーまたは返されたデータの詳細がコンソールのログに記録されます。サービスオブジェクトのメソッド呼び出しの一部として渡されるコールバック関数の例を、次に示します。

```
new AWS.EC2({apiVersion: '2014-10-01'}).describeInstances(function(error, data) {
  if (error) {
    console.log(error); // an error occurred
  } else {
    console.log(data); // request succeeded
  }
});
```

## リクエストオブジェクトとレスポンスオブジェクトへのアクセス
<a name="access-request-response"></a>

コールバック関数内で、JavaScript キーワード `this` は、ほとんどのサービスの基盤となる `AWS.Response` オブジェクトを参照します。次の例では、未加工のレスポンスデータとヘッダーをログに記録してデバッグを支援するため、`httpResponse` オブジェクトの `AWS.Response` プロパティをコールバック関数内で使用します。

```
new AWS.EC2({apiVersion: '2014-10-01'}).describeInstances(function(error, data) {
  if (error) {
    console.log(error); // an error occurred
    // Using this keyword to access AWS.Response object and properties
    console.log("Response data and headers: " + JSON.stringify(this.httpResponse));
  } else {
    console.log(data); // request succeeded
  }
});
```

また、`AWS.Response` オブジェクトには元のメソッド呼び出しによって送信された `Request` を含む `AWS.Request` プロパティがあるため、行われたリクエストの詳細にアクセスすることもできます。

# リクエストオブジェクトのイベントリスナーの使用
<a name="using-a-response-event-handler"></a>

サービスオブジェクトメソッドを呼び出すときに、無名コールバック関数を作成してパラメータとして渡さない場合、メソッド呼び出しは `AWS.Request` オブジェクトを生成します。このオブジェクトは `send` メソッドを使用して手動で送信する必要があります。

レスポンスを処理するには、`AWS.Request` オブジェクトのイベントリスナーを作成して、メソッド呼び出しのコールバック関数を登録する必要があります。次の例は、サービスオブジェクトメソッドを呼び出すための `AWS.Request` オブジェクトと、正常に返された場合のイベントリスナーを作成する方法を示しています。

```
// create the AWS.Request object
var request = new AWS.EC2({apiVersion: '2014-10-01'}).describeInstances();

// register a callback event handler
request.on('success', function(response) {
  // log the successful data response
  console.log(response.data); 
});

// send the request
request.send();
```

`send` オブジェクトの `AWS.Request` メソッドが呼び出された後、サービスオブジェクトが `AWS.Response` オブジェクトを受け取った時にイベントハンドラが実行されます。

`AWS.Request` オブジェクトの詳細については、 API リファレンスの「[https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) 」を参照してください。`AWS.Response` オブジェクトの詳細については、 API リファレンスの「[レスポンスオブジェクトの使用](the-response-object.md) 」または「[https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html)」を参照してください。

## 複数のコールバックの連結
<a name="response-chaining-callbacks"></a>

任意のリクエストオブジェクトで複数のコールバックを登録できます。複数のコールバックを異なるイベントに登録するか、または同じイベントに対して登録できます。また、次の例のようにコールバックを連結させることもできます。

```
request.
  on('success', function(response) {
    console.log("Success!");
  }).
  on('error', function(response) {
    console.log("Error!");
  }).
  on('complete', function() {
    console.log("Always!");
  }).
  send();
```

## リクエストオブジェクトの完了イベント
<a name="request-object-completion-events"></a>

`AWS.Request` オブジェクトは、各サービスオペレーションメソッドのレスポンスに基づいてこれらの完了イベントを発生させます。
+ `success`
+ `error`
+ `complete`

これらのイベントのいずれかに対応するコールバック関数を登録できます。すべてのリクエストオブジェクトイベントの完全なリストについては、API リファレンスの「[https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html)」を参照してください。

### 成功イベント
<a name="request-success-event"></a>

`success` イベントは、サービスオブジェクトから受け取った正常なレスポンスに応じて発生します。次に、このイベントのコールバック関数を登録する方法を示します。

```
request.on('success', function(response) { 
  // event handler code
});
```

レスポンスは、サービスからのシリアル化されたレスポンスデータを含む `data` プロパティを提供します。例えば、Amazon S3 サービスオブジェクトの `listBuckets` メソッドに対する以下の呼び出し

```
s3.listBuckets.on('success', function(response) {
  console.log(response.data);
}).send();
```

レスポンスを返してから、以下の `data` プロパティの内容をコンソールに出力します。

```
{ Owner: { ID: '...', DisplayName: '...' },
  Buckets: 
   [ { Name: 'someBucketName', CreationDate: someCreationDate },
     { Name: 'otherBucketName', CreationDate: otherCreationDate } ],
  RequestId: '...' }
```

### エラーイベント
<a name="request-error-event"></a>

`error` イベントは、サービスオブジェクトから受け取ったエラーレスポンスに応じて発生します。次に、このイベントのコールバック関数を登録する方法を示します。

```
request.on('error', function(error, response) { 
  // event handling code
});
```

`error` イベントが発生すると、レスポンスの `data` プロパティの値は `null` になり、`error` プロパティにはエラーデータが含まれます。関連付けられた `error` オブジェクトは、登録済みコールバック関数への最初のパラメータとして渡されます。たとえば、以下のコードは、

```
s3.config.credentials.accessKeyId = 'invalid';
s3.listBuckets().on('error', function(error, response) {
  console.log(error);
}).send();
```

エラーを返してから、以下のエラーデータをコンソールに出力します。

```
{ code: 'Forbidden', message: null }
```

### 完了イベント
<a name="request-complete-event"></a>

呼び出しが成功したか、エラーになったかにかかわらず、`complete` イベントはサービスオブジェクト呼び出しが終了したときに発生します。次に、このイベントのコールバック関数を登録する方法を示します。

```
request.on('complete', function(response) { 
  // event handler code
});
```

成功またはエラーに関係なく実行する必要があるすべてのリクエストのクリーンアップを処理するには、`complete` イベントコールバックを使用します。`complete` イベントのコールバック内でレスポンスデータを使用する場合は、次の例に示すように、どちらかにアクセスする前にまず `response.data` か `response.error` のプロパティを確認してください。

```
request.on('complete', function(response) {
  if (response.error) {
    // an error occurred, handle it
  } else {
    // we can use response.data here
  }
}).send();
```

## リクエストオブジェクトの HTTP イベント
<a name="request-object-http-events"></a>

`AWS.Request` オブジェクトは、各サービスオペレーションメソッドのレスポンスに基づいてこれらの HTTP イベントを発生させます。
+ `httpHeaders`
+ `httpData`
+ `httpUploadProgress`
+ `httpDownloadProgress`
+ `httpError`
+ `httpDone`

これらのイベントのいずれかに対応するコールバック関数を登録できます。すべてのリクエストオブジェクトイベントの完全なリストについては、API リファレンスの「[https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html)」を参照してください。

### httpHeaders イベント
<a name="request-httpheaders-event"></a>

`httpHeaders` イベントは、ヘッダーがリモートサーバーによって送信されたときに発生します。次に、このイベントのコールバック関数を登録する方法を示します。

```
request.on('httpHeaders', function(statusCode, headers, response) {
  // event handling code
});
```

コールバック関数の `statusCode` パラメータは HTTP ステータスコードです。`headers` パラメータにはレスポンスヘッダーが入ります。

### httpData イベント
<a name="request-httpdata-event"></a>

`httpData` イベントは、サービスからのレスポンスデータパケットをストリーミングするために発生します。次に、このイベントのコールバック関数を登録する方法を示します。

```
request.on('httpData', function(chunk, response) {
  // event handling code
});
```

通常、このイベントは、レスポンス全体をメモリにロードするのが現実的ではない場合に、大量のレスポンスをチャンクに分けて受信するために使用されます。このイベントには、サーバーからの実際のデータの一部を含む、追加の `chunk` パラメータがあります。

`httpData` イベントのコールバックを登録すると、レスポンスの `data` プロパティにはリクエスト用にシリアル化された出力全体が含まれます。組み込みハンドラ用の余分な解析とメモリーのオーバーヘッドがない場合、デフォルトの `httpData` リスナーを削除する必要があります。

### httpDownloadProgress と httpUploadProgress イベント
<a name="request-httpupload-download-progress-event"></a>

`httpUploadProgress` イベントは、HTTP リクエストがさらにデータをアップロードしたときに発生します。同様に、`httpDownloadProgress` イベントは、HTTP リクエストがさらにデータをダウンロードしたときに発生します。次に、これらのイベントのコールバック関数を登録する方法を示します。

```
request.on('httpUploadProgress', function(progress, response) {
  // event handling code
})
.on('httpDownloadProgress', function(progress, response) {
  // event handling code
});
```

コールバック関数の `progress` パラメータには、リクエストのロード済みバイト数と合計バイト数を含むオブジェクトが含まれています。

### httpError イベント
<a name="request-httperror-event"></a>

`httpError` イベントは、HTTP リクエストが失敗した場合に発生します。次に、このイベントのコールバック関数を登録する方法を示します。

```
request.on('httpError', function(error, response) {
  // event handling code
});
```

コールバック関数の `error` パラメータには、スローされたエラーが含まれています。

### httpDone イベント
<a name="request-httpdone-event"></a>

`httpDone` イベントは、サーバーのデータ送信が終了すると発生します。次に、このイベントのコールバック関数を登録する方法を示します。

```
request.on('httpDone', function(response) {
  // event handling code
});
```

# async/await の使用
<a name="using-async-await"></a>

AWS SDK for JavaScript への呼び出しで `async/await` パターンを使用できます。コールバックを受け取るほとんどの関数は、promise を返しません。promise を返す `await` 関数のみを使用するため、`async/await` パターンを使用するには、`.promise()` メソッドを呼び出しの最後にチェーンし、コールバックを削除する必要があります。

次の例では、async/await を使用して、すべての Amazon DynamoDB テーブルを `us-west-2` で一覧表示します。

```
var AWS = require("aws-sdk");
//Create an Amazon DynamoDB client service object.
dbClient = new AWS.DynamoDB({ region: "us-west-2" });
// Call DynamoDB to list existing tables
const run = async () => {
  try {
    const results = await dbClient.listTables({}).promise();
    console.log(results.TableNames.join("\n"));
  } catch (err) {
    console.error(err);
  }
};
run();
```

**注記**  
 すべてのブラウザが async/await をサポートしているわけではありません。非同期/待機をサポートするブラウザのリストについては、[非同期関数](https://caniuse.com/#feat=async-functions)を参照してください。

# JavaScript Promises の使用
<a name="using-promises"></a>

`AWS.Request.promise` メソッドは、コールバックを使用する代わりに、サービスオペレーションを呼び出して非同期フローを管理する方法を提供します。Node.js とブラウザスクリプトでは、コールバック関数なしでサービスオペレーションが呼び出された場合に `AWS.Request` オブジェクトが返されます。リクエストの `send` メソッドを呼び出して、サービスの呼び出しを行うことができます。

ただし、`AWS.Request.promise` はすぐにサービス呼び出しを開始し、レスポンス `data` プロパティで満たされるか、レスポンス `error` プロパティで拒否された promise のいずれかを返します。

```
var request = new AWS.EC2({apiVersion: '2014-10-01'}).describeInstances();

// create the promise object
var promise = request.promise();

// handle promise's fulfilled/rejected states
promise.then(
  function(data) {
    /* process the data */
  },
  function(error) {
    /* handle the error */
  }
);
```

次の例は、`data` オブジェクトで満たされるか、`error` オブジェクトで拒否された promise を返します。promises を使用すると、1 つのコールバックだけでエラーを検出することはありません。代わりに、リクエストの成功または失敗に基づいて、正しいコールバックが呼び出されます。

```
var s3 = new AWS.S3({apiVersion: '2006-03-01', region: 'us-west-2'});
var params = {
  Bucket: 'bucket',
  Key: 'example2.txt',
  Body: 'Uploaded text using the promise-based method!'
};
var putObjectPromise = s3.putObject(params).promise();
putObjectPromise.then(function(data) {
  console.log('Success');
}).catch(function(err) {
  console.log(err);
});
```

## 複数の Promises の調整
<a name="multiple-promises"></a>

状況によって、コードは複数の非同期呼び出しを行う必要があります。すべてが正常に返されたときのみ、これらの呼び出しに対する操作が必要です。これらの個々の非同期メソッド呼び出しを promises で管理する場合、`all` メソッドを使用する追加の promise を作成することができます。このメソッドは、ユーザーがメソッドに渡す promise の配列が満たされた場合に、この包括的な promise を満たします。コールバック関数には、`all` メソッドに渡された promises の値の配列が渡されます。

次の例で、AWS Lambda 関数は Amazon DynamoDB に対して 3 回の非同期呼び出しを行う必要があります。ただし、各呼び出しの promise が満たされた後にのみ完了することができます。

```
Promise.all([firstPromise, secondPromise, thirdPromise]).then(function(values) {
  
  console.log("Value 0 is " + values[0].toString);
  console.log("Value 1 is " + values[1].toString);
  console.log("Value 2 is " + values[2].toString);

  // return the result to the caller of the Lambda function
  callback(null, values);
});
```

## ブラウザおよび Node.js による Promises のサポート
<a name="browser-node-promise-support"></a>

ネイティブ JavaScript の promises (ECMAScript 2015) のサポートは、コードが実行される JavaScript エンジンとバージョンによって異なります。コードを実行する必要がある各環境における JavaScript のサポートを確認するには、GitHub の「[ECMAScript 適合表](https://compat-table.github.io/compat-table/es6/)」を参照してください。

## その他の Promise 実装の使用
<a name="using-other-promise-implementations"></a>

ECMAScript 2015 でのネイティブの promise 実装に加えて、以下を含むサードパーティーの promise ライブラリも使用できます。
+ [bluebird](http://bluebirdjs.com)
+ [RSVP](https://github.com/tildeio/rsvp.js/)
+ [Q](https://github.com/kriskowal/q)

これらオプションの promise ライブラリは、ECMAScript 5 および ECMAScript 2015 のネイティブの promise 実装をサポートしていない環境でコードを実行する必要がある場合に便利です。

サードパーティーの promise ライブラリを使用するには、グローバル設定オブジェクトの `setPromisesDependency` メソッドを呼び出して、SDK に promises の依存関係を設定します。ブラウザスクリプトでは、必ず SDK をロードする前にサードパーティーの promise ライブラリをロードしてください。次の例で、SDK は bluebird の promise ライブラリの実装を使用するように設定されています。

```
AWS.config.setPromisesDependency(require('bluebird'));
```

再び JavaScript エンジンのネイティブの promise 実装を使用するには、再度 `setPromisesDependency` を呼び出して、ライブラリ名の代わりに `null` を渡します。

# レスポンスオブジェクトの使用
<a name="the-response-object"></a>

サービスオブジェクトメソッドは呼び出されると、`AWS.Response` オブジェクトをコールバック関数に渡すことで返します。`AWS.Response` オブジェクトのプロパティを通じて、レスポンスの内容にアクセスします。レスポンスの内容へのアクセスに使用する `AWS.Response` オブジェクトには、2 つのプロパティがあります。
+ `data` プロパティ
+ `error` プロパティ

標準のコールバックメカニズムを使用する場合、次の例に示すように、これら 2 つのプロパティは無名コールバック関数のパラメータとして提供されています。

```
function(error, data) {
    if (error) {
        // error handling code
        console.log(error);
    } else {
        // data handling code
        console.log(data);
    }
}
```

## レスポンスオブジェクトで返されたデータへのアクセス
<a name="response-data-property"></a>

`data` オブジェクトの `AWS.Response` プロパティには、サービスリクエストによって戻された、シリアル化されたデータが含まれます。リクエストが成功すると、`data` プロパティには、返されたデータへのマップを含むオブジェクトが含まれます。エラーが発生した場合、`data` プロパティは null になることがあります。

これは、DynamoDB テーブルの `getItem` メソッドを呼び出して、ゲームの一部として使用するイメージファイルのファイル名を取得する例です。

```
// Initialize parameters needed to call DynamoDB
var slotParams = {
    Key : {'slotPosition' : {N: '0'}},
    TableName : 'slotWheels',
    ProjectionExpression: 'imageFile'
};

// prepare request object for call to DynamoDB
var request = new AWS.DynamoDB({region: 'us-west-2', apiVersion: '2012-08-10'}).getItem(slotParams);
// log the name of the image file to load in the slot machine
request.on('success', function(response) {
    // logs a value like "cherries.jpg" returned from DynamoDB
    console.log(response.data.Item.imageFile.S);
});
// submit DynamoDB request
request.send();
```

この例では、DynamoDB テーブルは `slotParams` のパラメータで指定されたスロットマシンプルの結果を示すイメージのルックアップです。

`getItem` メソッドの呼び出しが成功すると、`AWS.Response` オブジェクトの `data` プロパティには DynamoDB が返す `Item` オブジェクトが含まれます。返されるデータは、リクエストの `ProjectionExpression` パラメータに従ってアクセスされます。この場合、これは `imageFile` オブジェクトの `Item` メンバーを表しています。`imageFile` メンバーが文字列値を保持しているため、`S` の `imageFile` 子メンバーの値を通してイメージ自体のファイル名にアクセスします。

## 返されたデータによるページング
<a name="response-paged-data"></a>

サービスリクエストによって返された `data` プロパティの内容が複数のページにわたる場合があります。`response.nextPage` メソッドを呼び出すことで、次のページのデータにアクセスできます。このメソッドは新しいリクエストを送信します。リクエストからのレスポンスは、コールバックまたは、成功リスナーとエラーリスナーのどちらかでキャプチャできます。

`response.hasNextPage` メソッドを呼び出すことで、サービスリクエストによって返されたデータに追加のデータページがあるかどうかを確認できます。このメソッドは、`response.nextPage` を呼び出すと追加のデータが返されるかどうかを示すブール値を返します。

```
s3.listObjects({Bucket: 'bucket'}).on('success', function handlePage(response) {
    // do something with response.data
    if (response.hasNextPage()) {
        response.nextPage().on('success', handlePage).send();
    }
}).send();
```

## レスポンスオブジェクトからエラー情報へのアクセス
<a name="response-error-property"></a>

`error` オブジェクトの `AWS.Response` プロパティには、サービスエラーまたは転送エラーが発生した場合に利用可能なエラーデータが含まれます。返されるエラーは次の形式になります。

```
{ code: 'SHORT_UNIQUE_ERROR_CODE', message: 'a descriptive error message' }
```

エラーが発生した場合、`data` プロパティの値は `null` です。エラー状態にある可能性のあるイベントを処理する場合、`error` プロパティの値にアクセスする前に、`data` プロパティが設定されているかどうかを常に確認してください。

## 生成元リクエストオブジェクトへのアクセス
<a name="response-request-property"></a>

`request` プロパティは、生成元の `AWS.Request` オブジェクトへのアクセスを提供します。元の `AWS.Request` オブジェクトを参照して、送信された元のパラメータにアクセスするのに便利です。次の例では、`request` プロパティを使用して元のサービスリクエストの `Key` パラメータにアクセスします。

```
s3.getObject({Bucket: 'bucket', Key: 'key'}).on('success', function(response) {
   console.log("Key was", response.request.params.Key);
}).send();
```

# JSON の使用
<a name="working-with-json"></a>

JSON は、人間にも機械にも読み取り可能な、データ交換のための形式です。JSON という名前は、*JavaScript Object Notation* の頭字語ですが、JSON の形式はどのプログラミング言語にも依存しません。

SDK for JavaScript は、リクエストを行うときに JSON を使用してサービスオブジェクトにデータを送信し、サービスオブジェクトからデータを JSON として受信します。JSON の詳細については、[json.org](https://json.org) を参照してください。

![\[JSON の一般的なフォーマットと一部を表示しています。\]](http://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/images/json-format.png)


JSON は 2 つの方法でデータを表します。
+ *オブジェクト*は、順序が設定されていない一連の名前と値のペアです。オブジェクトは左中括弧 (`{`) と右中括弧 (`}`) で囲んで定義します。それぞれの名前と値のペアは名前で始まり、続けてコロン、その後に値が続きます。名前と値のペアはカンマで区切ります。
+ *配列*は、順序が設定された一連の値です。配列は左角括弧 (`[`) と右角括弧 (`]`) で囲んで定義します。配列の項目はカンマで区切ります。

これは、オブジェクトの配列を含む JSON オブジェクトの例です。オブジェクトは、カードゲームのカードを表しています。各カードは 2 つの名前と値のペアで定義されます。1 つはそのカードを識別するための一意の値を指定し、もう 1 つは対応するカードイメージを指す URL を指定します。

```
var cards = [{"CardID":"defaultname", "Image":"defaulturl"},
  {"CardID":"defaultname", "Image":"defaulturl"},
  {"CardID":"defaultname", "Image":"defaulturl"},
  {"CardID":"defaultname", "Image":"defaulturl"},
  {"CardID":"defaultname", "Image":"defaulturl"}];
```

## サービスオブジェクトパラメータとしての JSON
<a name="json-as-parameters-passed"></a>

次の例では、シンプルな JSON を使用して Lambda サービスオブジェクトへの呼び出しのパラメータを定義します。

```
var pullParams = {
   FunctionName : 'slotPull',
   InvocationType : 'RequestResponse',
   LogType : 'None'
};
```

`pullParams` オブジェクトは、左右の中括弧内にコンマで区切られた、3 つの名前と値のペアによって定義されています。サービスオブジェクトメソッドの呼び出しにパラメータを指定する場合、呼び出す予定のサービスオブジェクトメソッドのパラメータ名によって名前が決まります。Lambda 関数を呼び出すとき、`FunctionName`、`InvocationType`、および `LogType` は、Lambda サービスオブジェクトの `invoke` メソッドの呼び出しに使用されるパラメータです。

サービスオブジェクトのメソッド呼び出しにパラメータを渡すとき、次の Lambda 関数の呼び出しの例に示されているように、メソッド呼び出しに JSON オブジェクトを渡します。

```
lambda = new AWS.Lambda({region: 'us-west-2', apiVersion: '2015-03-31'});
// create JSON object for service call parameters
var pullParams = {
   FunctionName : 'slotPull',
   InvocationType : 'RequestResponse',
   LogType : 'None'
};                
// invoke Lambda function, passing JSON object
lambda.invoke(pullParams, function(err, data) {
   if (err) {
      console.log(err);
   } else {
      console.log(data);
   }
});
```

## データを JSON として返す
<a name="json-as-returned-data"></a>

JSON は、同時に複数の値を送信する必要があるアプリケーションの部分間でデータを渡すための標準的な方法を提供します。通常、API のクライアントクラスのメソッドは、コールバック関数に渡される `data` パラメータに JSON を返します。例えば、Amazon S3 クライアントクラスの `getBucketCors` メソッドの呼び出しは次のとおりです。

```
// call S3 to retrieve CORS configuration for selected bucket
s3.getBucketCors(bucketParams, function(err, data) {
  if (err) {
    console.log(err);
  } else if (data) {
    console.log(JSON.stringify(data));
  }
});
```

`data` の値は JSON オブジェクトです。この例では、指定された Amazon S3 バケットの現在の CORS 設定を記述する JSON です。

```
{
   "CORSRules": [
      {
          "AllowedHeaders":["*"],
          "AllowedMethods":["POST","GET","PUT","DELETE","HEAD"],
          "AllowedOrigins":["*"],
          "ExposeHeaders":[],
          "MaxAgeSeconds":3000
      }
   ]
}
```

# AWS SDK for JavaScript v2 での再試行戦略
<a name="retry-strategy"></a>

DNS サーバー、スイッチ、ロードバランサーなど、ネットワークの多数のコンポーネントが、特定のリクエストの存続期間中どこでもエラーを生成する可能性があります。ネットワーク環境でこれらのエラー応答を処理する通常の方法は、クライアントアプリケーションで再試行を実装することです。この技術は、アプリケーションの信頼性を向上させ、開発者の運用コストを削減します。AWSSDK は、AWS リクエストの自動再試行ロジックを実装します。

## エクスポネンシャルバックオフベースの再試行動作
<a name="retry-behavior"></a>

AWS SDK for JavaScript v2 は、[フルジッターによるエクスポネンシャルバックオフ](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/#Jitter)を使用して再試行ロジックを実装し、フロー制御を向上させます。エクスポネンシャルバックオフの背後にある考え方は、連続したエラー応答の再試行間の待機時間を徐々に長く使用することです。ジッター (ランダム化された遅延) は、連続する衝突を防ぐために使用されます。

### v2 での再試行遅延のテスト
<a name="w2aac18c37b5b5"></a>

v2 で再試行遅延をテストするために、[node\$1modules/aws-sdk/lib/event\$1listeners.js](https://github.com/aws/aws-sdk-js/blob/master/lib/event_listeners.js#L588) のコードが次のように変数遅延で存在する値 `console.log` に更新されました。

```
// delay < 0 is a signal from customBackoff to skip retries
if (willRetry && delay >= 0) {
  resp.error = null;
  console.log('retry delay: ' + delay);
  setTimeout(done, delay);
} else {
  done();
}
```

#### デフォルト設定で遅延を再試行する
<a name="w2aac18c37b5b5b7"></a>

AWS SDK クライアントでは、任意のオペレーションの遅延をテストできます。次のコードを使用して、DynamoDB クライアントで `listTables` オペレーションを呼び出します。

```
import AWS from "aws-sdk";

const region = "us-east-1";
const client = new AWS.DynamoDB({ region });
await client.listTables({}).promise();
```

再試行をテストするには、テストコードを実行しているデバイスからインターネットを切断して `NetworkingError` をシミュレートします。カスタムエラーを返すようにプロキシを設定することもできます。

コードを実行すると、次のようにジッターによるエクスポネンシャルバックオフを使用して再試行の遅延を確認できます。

```
retry delay: 7.39361151766359
retry delay: 9.0672860785882
retry delay: 134.89340825668168
retry delay: 398.53559817403965
retry delay: 523.8076165896343
retry delay: 1323.8789643058465
```

再試行ではジッターが使用されるため、サンプルコードの実行時には異なる値が得られます。

#### カスタムベースで遅延を再試行する
<a name="w2aac18c37b5b5b9"></a>

AWS SDK for JavaScript v2 では、オペレーションの再試行のためにエクスポネンシャルバックオフで使用するカスタムベースの数 (ミリ秒単位) を渡すことができます。DynamoDB を除くすべてのサービスでは、デフォルトで 100 ミリ秒に設定されます。DynamoDB では、デフォルトで 50 ミリ秒に設定されます。

次のように 1,000 ミリ秒のカスタムベースで再試行をテストします。

```
...
const client = new AWS.DynamoDB({ region, retryDelayOptions: { base: 1000 } });
...
```

テストコードを実行しているデバイスからインターネットを切断して `NetworkingError` をシミュレートします。再試行の遅延の値は、デフォルトが 50 または 100 ミリ秒であった以前の実行と比較して高いことがわかります。

```
retry delay: 356.2841549924913
retry delay: 1183.5216495444615
retry delay: 2266.997988094194
retry delay: 1244.6948354966453
retry delay: 4200.323030066383
```

再試行ではジッターが使用されるため、サンプルコードの実行時には異なる値が得られます。

#### カスタムバックオフアルゴリズムによる遅延の再試行
<a name="w2aac18c37b5b5c11"></a>

AWS SDK for JavaScript v2 では、再試行回数とエラーを受け入れ、遅延時間をミリ秒単位で返すカスタムバックオフ関数を渡すこともできます。結果が 0 以外の負の値の場合、それ以上の再試行は行われません。

次のように、基本値が 200 ミリ秒の線形バックオフを使用するカスタムバックオフ関数をテストします。

```
...
const client = new AWS.DynamoDB({
  region,
  retryDelayOptions: { customBackoff: (count, error) => (count + 1) * 200 },
});
...
```

テストコードを実行しているデバイスからインターネットを切断して `NetworkingError` をシミュレートします。再試行遅延の値は 200 の倍数であることがわかります。

```
retry delay: 200
retry delay: 400
retry delay: 600
retry delay: 800
retry delay: 1000
```