

The AWS SDK for JavaScript v2 has reached end-of-support. We recommend that you migrate to [AWS SDK for JavaScript v3](https://docs.aws.amazon.com//sdk-for-javascript/v3/developer-guide/). For additional details and information on how to migrate, please refer to this [announcement](https://aws.amazon.com/blogs//developer/announcing-end-of-support-for-aws-sdk-for-javascript-v2/).

# Working with Services in the SDK for JavaScript
<a name="working-with-services"></a>

The AWS SDK for JavaScript provides access to services that it supports through a collection of client classes. From these client classes, you create service interface objects, commonly called *service objects*. Each supported AWS service has one or more client classes that offer low-level APIs for using service features and resources. For example, Amazon DynamoDB APIs are available through the `AWS.DynamoDB` class.

The services exposed through the SDK for JavaScript follow the request-response pattern to exchange messages with calling applications. In this pattern, the code invoking a service submits an HTTP/HTTPS request to an endpoint for the service. The request contains parameters needed to successfully invoke the specific feature being called. The service that is invoked generates a response that is sent back to the requestor. The response contains data if the operation was successful or error information if the operation was unsuccessful. 

![\[The AWS request response service pattern.\]](http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/images/request-response.png)


Invoking an AWS service includes the full request and response lifecycle of an operation on a service object, including any retries that are attempted. A request is encapsulated in the SDK by the `AWS.Request` object. The response is encapsulated in the SDK by the `AWS.Response` object, which is provided to the requestor through one of several techniques, such as a callback function or a JavaScript promise.

**Topics**
+ [Creating and Calling Service Objects](creating-and-calling-service-objects.md)
+ [Logging AWS SDK for JavaScript Calls](logging-sdk-calls.md)
+ [Calling Services Asychronously](calling-services-asynchronously.md)
+ [Using the Response Object](the-response-object.md)
+ [Working with JSON](working-with-json.md)
+ [Retry strategy in the AWS SDK for JavaScript v2](retry-strategy.md)

# Creating and Calling Service Objects
<a name="creating-and-calling-service-objects"></a>

The JavaScript API supports most available AWS services. Each service class in the JavaScript API provides access to every API call in its service. For more information on service classes, operations, and parameters in the JavaScript API, see the [API reference](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/index.html).

When using the SDK in Node.js, you add the SDK package to your application using `require`, which provides support for all current services.

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

When using the SDK with browser JavaScript, you load the SDK package to your browser scripts using the AWS-hosted SDK package. To load the SDK package, add the following `<script>` element:

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

To find the current SDK\$1VERSION\$1NUMBER, see the API Reference for the SDK for JavaScript at [AWS SDK for JavaScript API Reference Guide](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/).

The default hosted SDK package provides support for a subset of the available AWS services. For a list of the default services in the hosted SDK package for the browser, see [Supported Services](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/#Supported_Services) in the API Reference. You can use the SDK with other services if CORS security checking is disabled. In this case, you can build a custom version of the SDK to include the additional services you require. For more information on building a custom version of the SDK, see [Building the SDK for Browsers](building-sdk-for-browsers.md).

## Requiring Individual Services
<a name="requiring-individual-services"></a>

Requiring the SDK for JavaScript as shown previously includes the entire SDK into your code. Alternately, you can choose to require only the individual services used by your code. Consider the following code used to create an Amazon S3 service object.

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

In the previous example, the `require` function specifies the entire SDK. The amount of code to transport over the network as well as the memory overhead of your code would be substantially smaller if only the portion of the SDK you require for the Amazon S3 service was included. To require an individual service, call the `require` function as shown, including the service constructor in all lower case.

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

Here is what the code to create the previous Amazon S3 service object looks like when it includes only the Amazon S3 portion of the SDK.

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

You can still access the global AWS namespace without every service attached to it.

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

This is a useful technique when applying the same configuration across multiple individual services, for example to provide the same credentials to all services. Requiring individual services should reduce loading time and memory consumption in Node.js. When done along with a bundling tool such as Browserify or webpack, requiring individual services results in the SDK being a fraction of the full size. This helps with memory or disk-space constrained environments such as an IoT device or in a Lambda function.

## Creating Service Objects
<a name="creating-service-objects"></a>

To access service features through the JavaScript API, you first create a *service object* through which you access a set of features provided by the underlying client class. Generally there is one client class provided for each service; however, some services divide access to their features among multiple client classes.

To use a feature, you must create an instance of the class that provides access to that feature. The following example shows creating a service object for DynamoDB from the `AWS.DynamoDB` client class.

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

By default, a service object is configured with the global settings also used to configure the SDK. However, you can configure a service object with runtime configuration data that is specific to that service object. Service-specific configuration data is applied after applying the global configuration settings.

In the following example, an Amazon EC2 service object is created with configuration for a specific Region but otherwise uses the global configuration.

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

In addition to supporting service-specific configuration applied to an individual service object, you can also apply service-specific configuration to all newly created service objects of a given class. For example, to configure all service objects created from the Amazon EC2 class to use the US West (Oregon) (`us-west-2`) Region, add the following to the `AWS.config` global configuration object.

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

## Locking the API Version of a Service Object
<a name="locking-api-version-of-service-objects"></a>

You can lock a service object to a specific API version of a service by specifying the `apiVersion` option when creating the object. In the following example, a DynamoDB service object is created that is locked to a specific API version.

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

For more information about locking the API version of a service object, see [Locking API Versions](locking-api-versions.md).

## Specifying Service Object Parameters
<a name="specifying-service-object-parameters"></a>

When calling a method of a service object, pass parameters in JSON as required by the API. For example, in Amazon S3, to get an object for a specified bucket and key, pass the following parameters to the `getObject` method. For more information about passing JSON parameters, see [Working with JSON](working-with-json.md).

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

For more information about Amazon S3 parameters, see [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html) in the API reference.

In addition, you can bind values to individual parameters when creating a service object using the `params` parameter. The value of the `params` parameter of service objects is a map that specifies one or more of the parameter values defined by the service object. The following example shows the `Bucket` parameter of an Amazon S3 service object being bound to a bucket named `amzn-s3-demo-bucket`.

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

By binding the service object to a bucket, the `s3bucket` service object treats the `amzn-s3-demo-bucket` parameter value as a default value that no longer needs to be specified for subsequent operations. Any bound parameter values are ignored when using the object for operations where the parameter value isn't applicable. You can override this bound parameter when making calls on the service object by specifying a new value. 

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

Details about available parameters for each method are found in the API reference.

# Logging AWS SDK for JavaScript Calls
<a name="logging-sdk-calls"></a>

The AWS SDK for JavaScript is instrumented with a built-in logger so you can log API calls you make with the SDK for JavaScript.

To turn on the logger and print log entries in the console, add the following statement to your code.

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

Here is an example of the log output.

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

## Using a Third-Party Logger
<a name="third-party-logger"></a>

You can also use a third-party logger, provided it has `log()` or `write()` operations to write to a log file or server. You must install and set up your custom logger as instructed before you can use it with the SDK for JavaScript.

One such logger you can use in either browser scripts or in Node.js is logplease. In Node.js, you can configure logplease to write log entries to a log file. You can also use it with webpack.

When using a third-party logger, set all options before assigning the logger to `AWS.Config.logger`. For example, the following specifies an external log file and sets the log level for 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;
```

For more information about logplease, see the [logplease Simple JavaScript Logger](https://github.com/haadcode/logplease) on GitHub.

# Calling Services Asychronously
<a name="calling-services-asynchronously"></a>

All requests made through the SDK are asynchronous. This is important to keep in mind when writing browser scripts. JavaScript running in a web browser typically has just a single execution thread. After making an asynchronous call to an AWS service, the browser script continues running and in the process can try to execute code that depends on that asynchronous result before it returns.

Making asynchronous calls to an AWS service includes managing those calls so your code doesn't try to use data before the data is available. The topics in this section explain the need to manage asynchronous calls and detail different techniques you can use to manage them.

**Topics**
+ [Managing Asychronous Calls](making-asynchronous-calls.md)
+ [Using an Anonymous Callback Function](using-a-callback-function.md)
+ [Using a Request Object Event Listener](using-a-response-event-handler.md)
+ [Using async/await](using-async-await.md)
+ [Using JavaScript Promises](using-promises.md)

# Managing Asychronous Calls
<a name="making-asynchronous-calls"></a>

For example, the home page of an e-commerce website lets returning customers sign in. Part of the benefit for customers who sign in is that, after signing in, the site then customizes itself to their particular preferences. To make this happen:

1. The customer must log in and be validated with their sign-in credentials.

1. The customer's preferences are requested from a customer database.

1. The database provides the customer's preferences that are used to customize the site before the page loads.

If these tasks execute synchronously, then each must finish before the next can start. The web page would be unable to finish loading until the customer preferences return from the database. However, after the database query is sent to the server, receipt of the customer data can be delayed or even fail due to network bottlenecks, exceptionally high database traffic, or a poor mobile device connection.

To keep the website from freezing under those conditions, call the database asychronously. After the database call executes, sending your asynchronous request, your code continues to execute as expected. If you don't properly manage the response of an asynchronous call, your code can attempt to use information it expects back from the database when that data isn't available yet.

![\[Showing difference between synchronous and asynchronous execution.\]](http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/images/async-vs-sync.png)


# Using an Anonymous Callback Function
<a name="using-a-callback-function"></a>

Each service object method that creates an `AWS.Request` object can accept an anonymous callback function as the last parameter. The signature of this callback function is:

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

This callback function executes when either a successful response or error data returns. If the method call succeeds, the contents of the response are available to the callback function in the `data` parameter. If the call doesn't succeed, the details about the failure are provided in the `error` parameter.

Typically the code inside the callback function tests for an error, which it processes if one is returned. If an error is not returned, the code then retrieves the data in the response from the `data` parameter. The basic form of the callback function looks like this example.

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

In the previous example, the details of either the error or the returned data are logged to the console. Here is an example that shows a callback function passed as part of calling a method on a service object.

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

## Accessing the Request and Response Objects
<a name="access-request-response"></a>

Within the callback function, the JavaScript keyword `this` refers to the underlying `AWS.Response` object for most services. In the following example, the `httpResponse` property of an `AWS.Response` object is used within a callback function to log the raw response data and headers to help with debugging.

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

In addition, because the `AWS.Response` object has a `Request` property that contains the `AWS.Request` that was sent by the original method call, you can also access the details of the request that was made.

# Using a Request Object Event Listener
<a name="using-a-response-event-handler"></a>

If you do not create and pass an anonymous callback function as a parameter when you call a service object method, the method call generates an `AWS.Request` object that must be manually sent using its `send` method.

To process the response, you must create an event listener for the `AWS.Request` object to register a callback function for the method call. The following example shows how to create the `AWS.Request` object for calling a service object method and the event listener for the successful return.

```
// 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();
```

After the `send` method on the `AWS.Request` object is called, the event handler executes when the service object receives an `AWS.Response` object.

For more information about the `AWS.Request` object, see [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) in the API Reference. For more information about the `AWS.Response` object, see [Using the Response Object](the-response-object.md) or [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html) in the API Reference.

## Chaining Multiple Callbacks
<a name="response-chaining-callbacks"></a>

You can register multiple callbacks on any request object. Multiple callbacks can be registered for different events or the same event. Also, you can chain callbacks as shown in the following example.

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

## Request Object Completion Events
<a name="request-object-completion-events"></a>

The `AWS.Request` object raises these completion events based on the response of each service operation method:
+ `success`
+ `error`
+ `complete`

You can register a callback function in response to any of these events. For a complete list of all request object events, see [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) in the API Reference.

### The success Event
<a name="request-success-event"></a>

The `success` event is raised upon a successful response received from the service object. Here is how you register a callback function for this event.

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

The response provides a `data` property that contains the serialized response data from the service. For example, the following call to the `listBuckets` method of the Amazon S3 service object

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

returns the response and then prints the following `data` property contents to the console.

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

### The error Event
<a name="request-error-event"></a>

The `error` event is raised upon an error response received from the service object. Here is how you register a callback function for this event.

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

When the `error` event is raised, the value of the response's `data` property is `null` and the `error` property contains the error data. The associated `error` object is passed as the first parameter to the registered callback function. For example, the following code:

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

returns the error and then prints the following error data to the console.

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

### The complete Event
<a name="request-complete-event"></a>

The `complete` event is raised when a service object call has finished, regardless of whether the call results in success or error. Here is how you register a callback function for this event.

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

Use the `complete` event callback to handle any request cleanup that must execute regardless of success or error. If you use response data inside a callback for the `complete` event, first check the `response.data` or `response.error` properties before attempting to access either one, as shown in the following example.

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

## Request Object HTTP Events
<a name="request-object-http-events"></a>

The `AWS.Request` object raises these HTTP events based on the response of each service operation method:
+ `httpHeaders`
+ `httpData`
+ `httpUploadProgress`
+ `httpDownloadProgress`
+ `httpError`
+ `httpDone`

You can register a callback function in response to any of these events. For a complete list of all request object events, see [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) in the API Reference.

### The httpHeaders Event
<a name="request-httpheaders-event"></a>

The `httpHeaders` event is raised when headers are sent by the remote server. Here is how you register a callback function for this event.

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

The `statusCode` parameter to the callback function is the HTTP status code. The `headers` parameter contains the response headers.

### The httpData Event
<a name="request-httpdata-event"></a>

The `httpData` event is raised to stream response data packets from the service. Here is how you register a callback function for this event.

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

This event is typically used to receive large responses in chunks when loading the entire response into memory is not practical. This event has an additional `chunk` parameter that contains a portion of the actual data from the server.

If you register a callback for the `httpData` event, the `data` property of the response contains the entire serialized output for the request. You must remove the default `httpData` listener if you don't have the extra parsing and memory overhead for the built-in handlers.

### The httpUploadProgress and httpDownloadProgress Events
<a name="request-httpupload-download-progress-event"></a>

The `httpUploadProgress` event is raised when the HTTP request has uploaded more data. Similarly, the `httpDownloadProgress` event is raised when the HTTP request has downloaded more data. Here is how you register a callback function for these events.

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

The `progress` parameter to the callback function contains an object with the loaded and total bytes of the request.

### The httpError Event
<a name="request-httperror-event"></a>

The `httpError` event is raised when the HTTP request fails. Here is how you register a callback function for this event.

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

The `error` parameter to the callback function contains the error that was thrown.

### The httpDone Event
<a name="request-httpdone-event"></a>

The `httpDone` event is raised when the server finishes sending data. Here is how you register a callback function for this event.

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

# Using async/await
<a name="using-async-await"></a>

You can use the `async/await` pattern in your calls to the AWS SDK for JavaScript. Most functions that take a callback do not return a promise. Since you only use `await` functions that return a promise, to use the `async/await` pattern you need to chain the `.promise()` method to the end of your call, and remove the callback.

The following example uses async/await to list all of your Amazon DynamoDB tables in `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();
```

**Note**  
 Not all browsers support async/await. See [Async functions](https://caniuse.com/#feat=async-functions) for a list of browsers with async/await support. 

# Using JavaScript Promises
<a name="using-promises"></a>

The `AWS.Request.promise` method provides a way to call a service operation and manage asynchronous flow instead of using callbacks. In Node.js and browser scripts, an `AWS.Request` object is returned when a service operation is called without a callback function. You can call the request's `send` method to make the service call.

However, `AWS.Request.promise` immediately starts the service call and returns a promise that is either fulfilled with the response `data` property or rejected with the response `error` property.

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

The next example returns a promise that's fulfilled with a `data` object, or rejected with an `error` object. Using promises, a single callback isn't responsible for detecting errors. Instead, the correct callback is called based on the success or failure of a request.

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

## Coordinating Multiple Promises
<a name="multiple-promises"></a>

In some situations, your code must make multiple asynchronous calls that require action only when they have all returned successfully. If you manage those individual asynchronous method calls with promises, you can create an additional promise that uses the `all` method. This method fulfills this umbrella promise if and when the array of promises that you pass into the method are fulfilled. The callback function is passed an array of the values of the promises passed to the `all` method.

In the following example, an AWS Lambda function must make three asynchronous calls to Amazon DynamoDB but can only complete after the promises for each call are fulfilled.

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

## Browser and Node.js Support for Promises
<a name="browser-node-promise-support"></a>

Support for native JavaScript promises (ECMAScript 2015) depends on the JavaScript engine and version in which your code executes. To help determine the support for JavaScript promises in each environment where your code needs to run, see the [ECMAScript Compatability Table](https://compat-table.github.io/compat-table/es6/) on GitHub.

## Using Other Promise Implementations
<a name="using-other-promise-implementations"></a>

In addition to the native promise implementation in ECMAScript 2015, you can also use third-party promise libraries, including:
+ [bluebird](http://bluebirdjs.com)
+ [RSVP](https://github.com/tildeio/rsvp.js/)
+ [Q](https://github.com/kriskowal/q)

These optional promise libraries can be useful if you need your code to run in environments that don't support the native promise implementation in ECMAScript 5 and ECMAScript 2015.

To use a third-party promise library, set a promises dependency on the SDK by calling the `setPromisesDependency` method of the global configuration object. In browser scripts, make sure to load the third-party promise library before loading the SDK. In the following example, the SDK is configured to use the implementation in the bluebird promise library.

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

To return to using the native promise implementation of the JavaScript engine, call `setPromisesDependency` again, passing a `null` instead of a library name.

# Using the Response Object
<a name="the-response-object"></a>

After a service object method has been called, it returns an `AWS.Response` object by passing it to your callback function. You access the contents of the response through the properties of the `AWS.Response` object. There are two properties of the `AWS.Response` object you use to access the contents of the response:
+ `data` property
+ `error` property

When using the standard callback mechanism, these two properties are provided as parameters on the anonymous callback function as shown in the following example.

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

## Accessing Data Returned in the Response Object
<a name="response-data-property"></a>

The `data` property of the `AWS.Response` object contains the serialized data returned by the service request. When the request is successful, the `data` property contains an object that contains a map to the data returned. The `data` property can be null if an error occurs.

Here is an example of calling the `getItem` method of a DynamoDB table to retrieve the file name of an image file to use as part of a game.

```
// 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();
```

For this example, the DynamoDB table is a lookup of images that show the results of a slot machine pull as specified by the parameters in `slotParams`.

Upon a successful call of the `getItem` method, the `data` property of the `AWS.Response` object contains an `Item` object returned by DynamoDB. The returned data is accessed according to the request's `ProjectionExpression` parameter, which in this case means the `imageFile` member of the `Item` object. Because the `imageFile` member holds a string value, you access the file name of the image itself through the value of the `S` child member of `imageFile`.

## Paging Through Returned Data
<a name="response-paged-data"></a>

Sometimes the contents of the `data` property returned by a service request span multiple pages. You can access the next page of data by calling the `response.nextPage` method. This method sends a new request. The response from the request can be captured either with a callback or with success and error listeners.

You can check to see if the data returned by a service request has additional pages of data by calling the `response.hasNextPage` method. This method returns a boolean to indicate whether calling `response.nextPage` returns additional data.

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

## Accessing Error Information from a Response Object
<a name="response-error-property"></a>

The `error` property of the `AWS.Response` object contains the available error data in the event of a service error or transfer error. The error returned takes the following form.

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

In the case of an error, the value of the `data` property is `null`. If you handle events that can be in a failure state, always check whether the `error` property was set before attempting to access the value of the `data` property.

## Accessing the Originating Request Object
<a name="response-request-property"></a>

The `request` property provides access to the originating `AWS.Request` object. It can be useful to refer to the original `AWS.Request` object to access the original parameters it sent. In the following example, the `request` property is used to access the `Key` parameter of the original service request.

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

# Working with JSON
<a name="working-with-json"></a>

JSON is a format for data exchange that is both human and machine-readable. While the name JSON is an acronym for *JavaScript Object Notation*, the format of JSON is independent of any programming language.

The SDK for JavaScript uses JSON to send data to service objects when making requests and receives data from service objects as JSON. For more information about JSON, see [json.org](https://json.org).

![\[Showing the general format and parts of JSON.\]](http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/images/json-format.png)


JSON represents data in two ways:
+ An *object*, which is an unordered collection of name-value pairs. An object is defined within left (`{`) and right (`}`) braces. Each name-value pair begins with the name, followed by a colon, followed by the value. Name-value pairs are comma separated.
+ An *array*, which is an ordered collection of values. An array is defined within left (`[`) and right (`]`) brackets. Items in the array are comma separated.

Here is an example of a JSON object that contains an array of objects in which the objects represent cards in a card game. Each card is defined by two name-value pairs, one that specifies a unique value to identify that card and another that specifies a URL that points to the corresponding card image.

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

## JSON as Service Object Parameters
<a name="json-as-parameters-passed"></a>

Here is an example of simple JSON used to define the parameters of a call to a Lambda service object.

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

The `pullParams` object is defined by three name-value pairs, separated by commas within the left and right braces. When providing parameters to a service object method call, the names are determined by the parameter names for the service object method you plan to call. When invoking a Lambda function, `FunctionName`, `InvocationType`, and `LogType` are the parameters used to call the `invoke` method on a Lambda service object.

When passing parameters to a service object method call, provide the JSON object to the method call, as shown in the following example of invoking a Lambda function.

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

## Returning Data as JSON
<a name="json-as-returned-data"></a>

JSON provides a standard way to pass data between parts of an application that need to send several values at the same time. The methods of client classes in the API commonly return JSON in the `data` parameter passed to their callback functions. For example, here is a call to the `getBucketCors` method of the Amazon S3 client class.

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

The value of `data` is a JSON object, in this example JSON that describes the current CORS configuration for a specified Amazon S3 bucket.

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

# Retry strategy in the AWS SDK for JavaScript v2
<a name="retry-strategy"></a>

Numerous components on a network, such as DNS servers, switches, load balancers, and others can generate errors anywhere in the life of a given request. The usual technique for dealing with these error responses in a networked environment is to implement retries in the client application. This technique increases the reliability of the application and reduces operational costs for the developer. AWS SDKs implement automated retry logic for your AWS requests.

## Exponential backoff based retry behavior
<a name="retry-behavior"></a>

The AWS SDK for JavaScript v2 implements retry logic using [exponential backoff with full jitter](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/#Jitter) for better flow control. The idea behind exponential backoff is to use progressively longer waits between retries for consecutive error responses. The jitter (randomized delay) is used to prevent successive collisions. 

### Testing retry delay in v2
<a name="w2aac18c37b5b5"></a>

In order to test retry delay in v2, the code in [node\$1modules/aws-sdk/lib/event\$1listeners.js](https://github.com/aws/aws-sdk-js/blob/master/lib/event_listeners.js#L588) was updated to `console.log` the value present in variable delay as follows: 

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

#### Retry delays with default configuration
<a name="w2aac18c37b5b5b7"></a>

You can test delay for any operation on AWS SDK clients. We call `listTables` operation on a DynamoDB client using the following code:

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

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

In order to test retries, we simulate `NetworkingError` by disconnecting internet from the device running the test code. You can also set up proxy to return a custom Error.

On running the code, you can see that retry delay using exponential backoff with jitter as follows:

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

As retry uses jitter, you will get different values in your run of the example code.

#### Retry delays with custom base
<a name="w2aac18c37b5b5b9"></a>

The AWS SDK for JavaScript v2 allows passing a custom base number of milliseconds to use in the exponential backoff for operation retries. It defaults to 100 ms for all services except DynamoDB, where it defaults to 50 ms.

We test retries with a custom base of 1000 ms as follows:

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

We simulate `NetworkingError` by disconnecting internet from the device running the test code. You can see that the values for retry delay are higher as compared to previous run where the default was 50 or 100 ms.

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

As retry uses jitter, you will get different values in your run of the example code.

#### Retry delays with custom backoff algorithm
<a name="w2aac18c37b5b5c11"></a>

The AWS SDK for JavaScript v2 also allows passing a custom backoff function that accepts a retry count and error and returns the amount of time to delay in milliseconds. If the result is a non-zero negative value, no further retry attempts will be made.

We test custom backoff function which uses linear backoff with base value of 200 ms as follows:

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

We simulate `NetworkingError` by disconnecting internet from the device running the test code. You can see that the values for retry delay are multiples of 200.

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