This document captures notable changes from AWS SDK for JavaScript v2 to v3. The v3 is also known as modular AWS SDK for JavaScript.
Because, v3 is a modular rewrite of v2, some basic conceptions are different between v2 and v3. You can learn about these changes in our blog posts. The following blog posts will get you up to speed:
- Modular packages in AWS SDK for JavaScript
- Introducing Middleware Stack in Modular AWS SDK for JavaScript
The summary of interface changes from AWS SDK for JavaScript v2 to v3 is given below. The goal is to help you easily find the v3 equivalents of the v2 APIs you are already familiar with.
This list is indexed by v2 config parameters.
-
- v2: Whether to compute MD5 checksums for payload bodies when the service accepts it (currently supported in S3 only).
- v3: applicable commands of S3 (PutObject, PutBucketCors, etc.) will automatically compute the MD5 checksums for
of the request payload. You can also specify a different checksum algorithm in the commands'
ChecksumAlgorithm
parameter to use a different checksum algorithm. You can find more infomation in the S3 feature announcement
-
- v2: Whether types are converted when parsing response data.
- v3: Deprecated. This option is considered not type-safe because it doesn't convert the types like time stamp or base64 binaries from the JSON response.
-
- v2: Whether to apply a clock skew correction and retry requests that fail because of an skewed client clock.
- v3: Deprecated. SDK always applies a clock skew correction.
-
- v2: An offset value in milliseconds to apply to all signing times.
- v3: No change.
-
- v2: The AWS credentials to sign requests with.
- v3: No change. It can also be an async function that returns credentials. If the function returns an
expiration (Date)
, the function will be called again when the expiration datetime nears. See v3 reference for AwsAuthInputConfig credentials.
-
- v2: The size of the global cache storing endpoints from endpoint discovery operations.
- v3: No change.
-
- v2: Whether to call operations with endpoints given by service dynamically.
- v3: No change.
-
- v2: Whether to marshal request parameters to the prefix of hostname.
- v3: Deprecated. SDK always injects the hostname prefix when necessary.
-
A set of options to pass to the low-level HTTP request. These options are aggregated differently in v3. You can configure them by supplying a new
requestHandler
. Here's the example of setting http options in Node.js runtime. You can find more in v3 reference for NodeHttpHandler.All v3 requests use HTTPS by default. You can provide a custom agent via the
httpsAgent
field of theNodeHttpHandler
constructor input.const { Agent } = require("https"); const { NodeHttpHandler } = require("@smithy/node-http-handler"); const dynamodbClient = new DynamoDBClient({ requestHandler: new NodeHttpHandler({ httpsAgent: new Agent({ /*params*/ }), connectionTimeout: /*number in milliseconds*/, socketTimeout: /*number in milliseconds*/ }), });
If you are using a custom endpoint which uses http, then you can provide an
httpAgent
.const { Agent } = require("http"); const { NodeHttpHandler } = require("@smithy/node-http-handler"); const dynamodbClient = new DynamoDBClient({ endpoint: "http://example.com", requestHandler: new NodeHttpHandler({ httpAgent: new Agent({ /*params*/ }), }), });
If the client is running in browsers, a different set of options is available. You can find more in v3 reference for FetchHttpHandler.
const { FetchHttpHandler } = require("@smithy/fetch-http-handler"); const dynamodbClient = new DynamoDBClient({ requestHandler: new FetchHttpHandler({ requestTimeout: /*number in milliseconds*/ }), });
Each option of
httpOptions
is specified below:-
proxy
- v2: The URL to proxy requests through
- v3: You can set up a proxy with an agent following Configuring proxies for Node.js
-
agent
- v2: The Agent object to perform HTTP requests with. Used for connection pooling.
- v3: You can configure
httpAgent
orhttpsAgent
as shown in the examples above.
-
connectTimeout
- v2: Sets the socket to timeout after failing to establish a connection with the server after connectTimeout milliseconds.
- v3:
connectionTimeout
is available inNodeHttpHandler
options.
-
timeout
- v2: The number of milliseconds a request can take before automatically being terminated.
- v3:
socketTimeout
is available inNodeHttpHandler
options.
-
xhrAsync
- v2: Whether the SDK will send asynchronous HTTP requests.
- v3: Deprecated. Requests are always asynchronous.
-
xhrWithCredentials
- v2: Sets the "withCredentials" property of an XMLHttpRequest object.
- v3: the
fetch
equivalent fieldcredentials
can be set via constructor configuration to therequestHandler
config when using the browser defaultFetchHttpHandler
.
-
-
- v2: An object that responds to .write() (like a stream) or .log() (like the console object) in order to log information about requests.
- v3: No change. More granular logs are available in v3.
-
- v2: The maximum amount of redirects to follow for a service request.
- v3: Deprecated. SDK does not follow redirects to avoid unintentional cross-region requests. S3 region redirects can be enabled separately with
followRegionRedirects=true
in the S3 Client only.
-
- v2: The maximum amount of retries to perform for a service request.
- v3: Changed to
maxAttempts
. See more in v3 reference for RetryInputConfig. Note that themaxAttempt
should bemaxRetries + 1
.
-
- v2: Whether input parameters should be validated against the operation description before sending the request.
- v3: Deprecated. SDK does not do validation on client-side at runtime.
-
- v2: The region to send service requests to.
- v3: No change. It can also be an async function that returns a region string.
-
- v2: A set of options to configure the retry delay on retryable errors.
- v3: Deprecated. SDK supports more flexible retry strategy with
retryStrategy
client constructor option. See more in v3 reference
-
- v2: Whether the provided endpoint addresses an individual bucket (false if it addresses the root API endpoint).
- v3: Changed to
bucketEndpoint
. See more in v3 reference for bucketEndpoint. Note that when set totrue
, you specify the request endpoint in theBucket
request parameter, the original endpoint will be overwritten. Whereas in v2, the request endpoint in client constructor overwrites theBucket
request parameter.
-
- v2: Whether to disable S3 body signing when using signature version v4.
- v3: Renamed to
applyChecksum
-
- v2: Whether to force path style URLs for S3 objects.
- v3: Renamed to
forcePathStyle
-
- v2: Whether to override the request region with the region inferred from requested resource's ARN.
- v3: Renamed to
useArnRegion
-
- v2: When region is set to 'us-east-1', whether to send s3 request to global endpoints or 'us-east-1' regional endpoints.
- v3: Deprecated. S3 client will always use regional endpoint if region is set to
us-east-1
. You can set the region toaws-global
to send requests to S3 global endpoint.
-
- v2: Whether the signature to sign requests with (overriding the API configuration) is cached.
- v3: Deprecated. SDK always caches the hashed signing keys.
-
- v2: The signature version to sign requests with (overriding the API configuration).
- v3: Deprecated. Signature V2 supported in v2 SDK has been deprecated by AWS. v3 only supports signature v4.
-
- v2: Whether SSL is enabled for requests.
- v3: Renamed to
tls
.
-
- v2: Whether to send sts request to global endpoints or regional endpoints.
- v3: Deprecated. STS client will always use regional endpoints if set to a specific region. You can set the
region to
aws-global
to send request to STS global endpoint.
-
- v2: Whether to use the Accelerate endpoint with the S3 service.
- v3: No change.
Top level fields such as error.code
and http response metadata like the
status code have slightly moved locations within the thrown error object
to subfields like error.$metadata
or error.$response
.
This is because v3 more accurately follows the service models and avoids adding metadata at the top level of the error object, which may conflict with the structural error shape modeled by the services.
See how error handling has changed in v3 here: ERROR_HANDLING.
In v2, the SDK provides a list of credential providers to choose from, as well as a credentials provider chain, available by default on Node.js, that tries to load the AWS credentials from all the most common providers. V3 simplifies the credential provider's interface, making it easier to use and write custom credential providers. On top of a new credentials provider chain, V3 all provides a list of credential providers aiming to provide equivalent to v2.
Here is all the credential providers in v2 and their equivalents in v3.
Default credential provider is how SDK resolve the AWS credential if you DO NOT provide one explicitly.
-
v2: CredentialProviderChain in Node.js resolves credential from sources as following order:
- environmental variable
- shared credentials file
- ECS container credentials
- spawning external process
- OIDC token from specified file
- EC2 instance metadata
If one of the credential providers above fails to resolve the AWS credential, the chain falls back to next provider until a valid credential is resolved, or throw error when all of them fail.
In Browsers and ReactNative, the chain is empty, meaning you always need supply credentials explicitly.
-
v3: defaultProvider The credential sources and fallback order does not change in v3. It also supports AWS Single Sign-On credentials.
-
v2:
ChainableTemporaryCredentials
Represents temporary credentials retrieved fromAWS.STS
. Without any extra parameters, credentials will be fetched from theAWS.STS.getSessionToken()
operation. If an IAM role is provided, theAWS.STS.assumeRole()
operation will be used to fetch credentials for the role instead.AWS.ChainableTemporaryCredentials
differs fromAWS.TemporaryCredentials
in the way masterCredentials and refreshes are handled.AWS.ChainableTemporaryCredentials
refreshes expired credentials using the masterCredentials passed by the user to support chaining of STS credentials. However,AWS.TemporaryCredentials
recursively collapses the masterCredentials during instantiation, precluding the ability to refresh credentials which require intermediate, temporary credentials.The original
TemporaryCredentials
has been deprecated in favor ofChainableTemporaryCredentials
in v2. -
v3:
Temporary Credentials Provider
. You can callfromTemporaryCredentials()
from@aws-sdk/credential-providers
package. Here's an example:import { FooClient } from "@aws-sdk/client-foo"; import { fromTemporaryCredentials } from "@aws-sdk/credential-providers"; // ES6 import // const { FooClient } = require("@aws-sdk/client-foo"); // const { fromTemporaryCredentials } = require("@aws-sdk/credential-providers"); // CommonJS import const sourceCredentials = { // A credential can be a credential object or an async function that returns a credential object }; const client = new FooClient({ credentials: fromTemporaryCredentials({ masterCredentials: sourceCredentials, params: { RoleArn }, }), });
Load credentials from Cognito Identity service, normally used in browsers.
-
v2:
CognitoIdentityCredentials
Represents credentials retrieved from STS Web Identity Federation using the Amazon Cognito Identity service. -
v3:
Cognito Identity Credential Provider
The@aws/credential-providers
package provides two credential provider functions, one of whichfromCognitoIdentity
takes an identity ID and callscognitoIdentity:GetCredentialsForIdentity
, while the otherfromCognitoIdentityPool
takes an identity pool ID, callscognitoIdentity:GetId
on the first invocation, and then callsfromCognitoIdentity
. Subsequent invocations of the latter do not re-invoke GetIdThe provider implements the "Simplified Flow" described in the Cognito developer guide. The "Classic Flow" which involves calling
cognito:GetOpenIdToken
and then callingsts:AssumeRoleWithWebIdentity
is NOT supported. Please open a feature request to us if you need it.// fromCognitoIdentityPool example import { fromCognitoIdentityPool } from "@aws-sdk/credential-providers"; // ES6 import // const { fromCognitoIdentityPool } = require("@aws-sdk/credential-providers"); // CommonJS import const client = new FooClient({ region: "us-east-1", credentials: fromCognitoIdentityPool({ clientConfig: cognitoIdentityClientConfig, // Optional identityPoolId: "us-east-1:1699ebc0-7900-4099-b910-2df94f52a030", customRoleArn: "arn:aws:iam::1234567890:role/MYAPP-CognitoIdentity", // Optional logins: { // Optional "graph.facebook.com": "FBTOKEN", "www.amazon.com": "AMAZONTOKEN", "api.twitter.com": "TWITTERTOKEN", }, }), });
// fromCognitoIdentity example import { fromCognitoIdentity } from "@aws-sdk/credential-providers"; // ES6 import // const { fromCognitoIdentity } = require("@aws-sdk/credential-provider-cognito-identity"); const client = new FooClient({ region: "us-east-1", credentials: fromCognitoIdentity({ clientConfig: cognitoIdentityClientConfig, // Optional identityId: "us-east-1:128d0a74-c82f-4553-916d-90053e4a8b0f", customRoleArn: "arn:aws:iam::1234567890:role/MYAPP-CognitoIdentity", // Optional logins: { // Optional "graph.facebook.com": "FBTOKEN", "www.amazon.com": "AMAZONTOKEN", "api.twitter.com": "TWITTERTOKEN", }, }), });
Represents credentials received from the metadata service on an EC2 instance.
-
v3:
fromInstanceMetadata
: Creates a credential provider that will source credentials from the EC2 Instance Metadata Service.import { fromInstanceMetadata } from "@aws-sdk/credential-providers"; // ES6 import // const { fromInstanceMetadata } = require("@aws-sdk/credential-providers"); // CommonJS import const client = new FooClient({ credentials: fromInstanceMetadata({ maxRetries: 3, // Optional timeout: 0, // Optional }), });
Represents credentials received from specified URL. This provider will request temporary credentials from
URI specified by the AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
or the AWS_CONTAINER_CREDENTIALS_FULL_URI
environment
variable.
-
v2:
ECSCredentials
orRemoteCredentials
. -
v3:
fromContainerMetadata
creates a credential provider that will source credentials from the ECS Container Metadata Service.import { fromContainerMetadata } from "@aws-sdk/credential-providers"; // ES6 import const client = new FooClient({ credentials: fromContainerMetadata({ maxRetries: 3, // Optional timeout: 0, // Optional }), });
- v2:
FileSystemCredentials
represents credentials from a JSON file on disk. - v3: Deprecated. You can explicitly read the JSON file and supply to the client. Please open a feature request to us if you need it.
- v2:
SAMLCredentials
represents credentials retrieved from STS SAML support. - v3: Not available. Please open a feature request to us if you need it.
Loads credentials from shared credentials file (defaulting to ~/.aws/credentials
or defined by the
AWS_SHARED_CREDENTIALS_FILE
environment variable). This file is supported across different AWS SDKs and tools. You can
refer to the shared config and credentials files document
for more information.
-
v3:
fromIni
.import { fromIni } from "@aws-sdk/credential-providers"; // const { fromIni } from("@aws-sdk/credential-providers"); const client = new FooClient({ credentials: fromIni({ configFilepath: "~/.aws/config", // Optional filepath: "~/.aws/credentials", // Optional mfaCodeProvider: async (mfaSerial) => { // implement a pop-up asking for MFA code return "some_code"; }, // Optional profile: "default", // Optional clientConfig: { region }, // Optional }), });
Retrieves credentials using OIDC token from a file on disk. It's commonly used in EKS.
-
v3:
fromTokenFile
import { fromTokenFile } from "@aws-sdk/credential-providers"; // ES6 import // const { fromTokenFile } from("@aws-sdk/credential-providers"); // CommonJS import const client = new FooClient({ credentials: fromTokenFile({ // Optional. If skipped, read from `AWS_ROLE_ARN` environmental variable roleArn: "arn:xxxx", // Optional. If skipped, read from `AWS_ROLE_SESSION_NAME` environmental variable roleSessionName: "session:a", // Optional. STS client config to make the assume role request. clientConfig: { region }, }), });
Retrieves credentials from STS web identity federation support.
-
v3:
fromWebToken
import { fromWebToken } from "@aws-sdk/credential-providers"; // ES6 import // const { fromWebToken } from("@aws-sdk/credential-providers"); // CommonJS import const client = new FooClient({ credentials: fromWebToken({ // Optional. If skipped, read from `AWS_ROLE_ARN` environmental variable roleArn: "arn:xxxx", // Optional. If skipped, read from `AWS_ROLE_SESSION_NAME` environmental variable roleSessionName: "session:a", // Optional. STS client config to make the assume role request. clientConfig: { region }, }), });
In v2, the S3 client has the ManagedUpload
class that contains an upload()
operation that supports uploading large objects with multipart upload feature offered by S3.
In v3, @aws-sdk/lib-storage
package is available.
It supports all the features offered in v2 upload()
, and supports both Node.js and browsers runtime.
In v2, the S3 client contains getSignedUrl()
and getSignedUrlPromise()
operations to generate an URL that users can use to upload or download objects from S3.
In v3, @aws-sdk/s3-request-presigner
package
is available. You don't have to differentiate getSignedUrl()
and getSignedUrlPromise()
any more. We also have a blog
discussing the details of this package.
S3 client in v3 supports S3 global client, or following region redirects, if an incorrect region is passed and a subsequent PermanentRedirect
(status 301) error is thrown. You can use the followRegionRedirects
flag in the client config to make the S3 client follow region redirects and support its function as a global client. Note that this can result in additional latency as failed requests are retried with a corrected region when receiving a PermanentRedirect
error with status 301. This feature should only be used as a last resort if you do not know the region of your bucket(s) ahead of time.
-
In v2, you can use the
AWS.DynamoDB.DocumentClient
class to call DynamoDB API with native JavaScript types like Array, Number, and Object. It thus simplifies working with items in Amazon DynamoDB by abstracting away the notion of attribute values. -
In v3, the equivalent
@aws-sdk/lib-dynamodb
is available. It's similar to normal service clients from v3 SDK, with the difference that it takes a basic DynamoDB client in its constructor.
Example:
import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; // ES6 import
// const { DynamoDBClient } = require("@aws-sdk/client-dynamodb"); // CommonJS import
import { DynamoDBDocumentClient, PutCommand } from "@aws-sdk/lib-dynamodb"; // ES6 import
// const { DynamoDBDocumentClient, PutCommand } = require("@aws-sdk/lib-dynamodb"); // CommonJS import
// Bare-bones DynamoDB Client
const client = new DynamoDBClient({});
// Bare-bones document client
const ddbDocClient = DynamoDBDocumentClient.from(client); // client is DynamoDB client
await ddbDocClient.send(
new PutCommand({
TableName,
Item: {
id: "1",
content: "content from DynamoDBDocumentClient",
},
})
);
-
In v2,
undefined
values in objects were automatically omitted during the marshalling process to DynamoDB. -
In v3, the default marshalling behavior in @aws-sdk/lib-dynamodb has changed: objects with
undefined
values are no longer omitted. To align with v2's functionality, developers must explicitly set theremoveUndefinedValues
totrue
in themarshallOptions
of the DynamoDBDocumentClient.
Example:
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, PutCommand } from "@aws-sdk/lib-dynamodb";
const client = new DynamoDBClient({});
// The DynamoDBDocumentClient is configured to handle undefined values properly
const ddbDocClient = DynamoDBDocumentClient.from(client, {
marshallOptions: {
removeUndefinedValues: true
}
});
await ddbDocClient.send(
new PutCommand({
TableName,
Item: {
id: "123",
content: undefined // This value will be automatically omitted
};
})
);
More examples and configurations are available in the package README.
In v2, all waiters are bound to the service client class, you need to specify in waiter's input which designed state the
client will be waiting for. For example, you need to call waitFor("bucketExists")
to wait for a newly created bucket to be ready.
In v3, you don't need to import waiters if your application doesn't need one. Moreover, you can import only the waiter you need to wait for the particular desired state you want. Thus, you can reduce your bundle size and improve performance. Here's the example of waiting for bucket to be ready after creation:
import { S3Client, CreateBucketCommand, waitUntilBucketExists } from "@aws-sdk/client-s3"; // ES6 import
// const { S3Client, CreateBucketCommand, waitUntilBucketExists } = require("@aws-sdk/client-s3"); // CommonJS import
const Bucket = "BUCKET_NAME";
const client = new S3Client({ region: "REGION" });
const command = new CreateBucketCommand({ Bucket });
await client.send(command);
await waitUntilBucketExists({ client, maxWaitTime: 60 }, { Bucket });
You can find everything of how to configure the waiters in the blog post of waiters in v3 SDK.
In v2, you can sign the request to access restricted CloudFront distributions with AWS.CloudFront.Signer
.
In v3, you have the same utilities provided in the @aws-sdk/cloudfront-signer
package.
In v2, you can generate the auth token to an RDS database using AWS.RDS.Signer
.
In v3, the similar utility class is available in @aws-sdk/rds-signer
package.
In v2, you can generate a signed URL to the speech synthesized by AWS Polly service with AWS.Polly.Presigner
class.
In v3, the similar utility function is available in @aws-sdk/polly-request-presigner
package
Streaming vs. buffered responses: the JSv3 SDK prefers not to buffer potentially large responses. This is commonly encountered in S3's GetObject operation, which returned a Buffer
in JSv2, but
returns a Stream
in JSv3.
For Node.js, you must consume the stream or garbage collect the client or its request handler to keep the connections open to new traffic by freeing sockets.
// v2
const get = await s3.getObject({ ... }).promise(); // this buffers (consumes) the stream already.
// v3, consume the stream to free the socket.
const get = await s3.getObject({ ... }); // object .Body has unconsumed stream.
const str = await get.Body.transformToString(); // consumes the stream.
// other ways to consume the stream include writing it to a file,
// passing it to another consumer like an upload, or buffering to
// a string or byte array.
Please see also the section on socket exhaustion here: https://github.com/aws/aws-sdk-js-v3/blob/main/supplemental-docs/CLIENTS.md#request-handler-requesthandler
Lambda invocations response type differs in v3:
import { Lambda } from "@aws-sdk/client-lambda";
import AWS from "aws-sdk";
const region = "...";
{
// v2
const lambda = new AWS.Lambda({ region });
const invoke = await lambda
.invoke({
FunctionName: "echo",
Payload: JSON.stringify({ message: "hello" }),
})
.promise();
// in v2, Lambda::invoke::Payload is automatically converted to string via a
// specific code customization.
const payloadIsString = typeof invoke.Payload === "string";
console.log("Invoke response payload type is string:", payloadIsString);
const payloadObject = JSON.parse(invoke.Payload);
console.log("Invoke response object", payloadObject);
}
{
const lambda = new Lambda({ region });
const invoke = await lambda.invoke({
FunctionName: "echo",
Payload: JSON.stringify({ message: "hello" }),
});
// in v3, Lambda::invoke::Payload is not automatically converted to a string.
// This is to reduce the number of customizations that create inconsistent behaviors.
const payloadIsByteArray = invoke.Payload instanceof Uint8Array;
console.log("Invoke response payload type is Uint8Array:", payloadIsByteArray);
// To maintain the old functionality, only one additional method call is needed:
// v3 adds a method to the Uint8Array called transformToString.
const payloadObject = JSON.parse(invoke.Payload.transformToString());
console.log("Invoke response object", payloadObject);
}
To skip computation of MD5 checksums of message bodies, set md5=false
on the configuration object.
Otherwise, by default the SDK will calculate the checksum for sending messages, as well as validating the checksum
for retrieved messages.
// Example: skip md5 checksum in SQS.
import { SQS } from "@aws-sdk/client-sqs";
new SQS({
md5: false, // Note: only available in v3.547.0 and higher.
});
When using a custom QueueUrl
in SQS operations that have this as an input parameter, in JSv2
it was possible to supply a custom QueueUrl
which would override the SQS Client's default endpoint.
You should use one client per region in v3. The AWS Region is meant to be initialized at the client level and not changed between requests.
import { SQS } from "@aws-sdk/client-sqs";
const sqsClients = {
"us-east-1": new SQS({ region: "us-east-1" }),
"us-west-2": new SQS({ region: "us-west-2" }),
};
const queues = [
{ region: "us-east-1", url: "https://sqs.us-east-1.amazonaws.com/{AWS_ACCOUNT}/MyQueue" },
{ region: "us-west-2", url: "https://sqs.us-west-2.amazonaws.com/{AWS_ACCOUNT}/MyOtherQueue" },
];
for (const { region, url } of queues) {
const params = {
MessageBody: "Hello",
QueueUrl: url,
};
await sqsClients[region].sendMessage(params);
}
In JSv3, when using a custom endpoint, i.e. one that differs from the default public SQS endpoints, you
should always set the endpoint on the SQS Client as well as the QueueUrl
field.
import { SQS } from "@aws-sdk/client-sqs";
const sqs = new SQS({
// client endpoint should be specified in JSv3 when not the default public SQS endpoint for your region.
// This is required for versions <= v3.506.0
// This is optional but recommended for versions >= v3.507.0 (a warning will be emitted)
endpoint: "https://my-custom-endpoint:8000/",
});
await sqs.sendMessage({
QueueUrl: "https://my-custom-endpoint:8000/1234567/MyQueue",
Message: "hello",
});
If you are not using a custom endpoint, then you do not need to set endpoint
on the client.
import { SQS } from "@aws-sdk/client-sqs";
const sqs = new SQS({
region: "us-west-2",
});
await sqs.sendMessage({
QueueUrl: "https://sqs.us-west-2.amazonaws.com/1234567/MyQueue",
Message: "hello",
});