What's new about AWS SDK for JavaScript v3?

Michael Wittig – 03 Feb 2021

The AWS SDK for JavaScript v3 is generally available since December 2020. This challenge unites all AWS users: is this new version worth investing your precious time?

Migrating to AWS SDK for JavaScript v3

In this blog post, I show you the new capabilities and use cases where they help you most, no matter if you use JavaScript on the frontend or the backend (Node.js). Let’s get started.

Pagination

Many AWS APIs could potentially return a long list of data (e.g., list all S3 objects in a bucket). All list APIs offer a paging mechanism to retrieve one batch at a time. Each batch contains a token to retrieve the next batch or indicate that you reached the list’s end. Good old v2 code with callbacks looked like this:

const AWS = require('aws-sdk');

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

function fetchPage(lastEvaluatedKey, cb) {
const params = {
TableName: 'users',
Limit: 100,
};
if (lastEvaluatedKey) {
params.ExclusiveStartKey = lastEvaluatedKey;
}
dynamodb.scan(params, cb);
}

function fetchAll(cb) {
fetchPage(null, function(err, data) {
if (err) {
cb(err);
} else {
data.Items.forEach(console.log);
if (data.LastEvaluatedKey) {
process.nextTick(() => fetchPage(data.LastEvaluatedKey, cb));
} else {
cb();
}
}
});
}

fetchAll(function (err) {
if (err) {
// panic
process.exit(1);
} else {
console.log('done');
}
});

Luckily, the JavaScript language evolved. We now have Promises, async/await, and generators. That’s why we can now write the following using the v3 SDK:

import { DynamoDBClient, paginateScan } from '@aws-sdk/client-dynamodb';

const dynamodb = new DynamoDBClient({apiVersion: '2012-08-10'});

async function fetchAll() {
const config = {
client: dynamodb,
pageSize: 100
};
const input = {
TableName: 'users'
};
const paginator = paginateScan(config, input);
for await (const page of paginator) {
page.Items.forEach(console.log);
}
}

fetchAll()
.then(() => console.log('done'))
.catch(() => process.exit(1));

I’m happy that I don’t have to write pagination code anymore. Keep in mind that in almost all user-facing scenarios, you should avoid getting all items at once. It will take a long time, and you might run out of memory! I believe that backend developers benefit most from this feature when they write “batch job” code.

Promises

Many programmers prefer promises over the callback approach. A callback approach using the v2 SDK looks like this:

const AWS = require('aws-sdk');

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

dynamodb.getItem({/*...*/}, function(err, data) {
// this code is invoked as soon as the result is available
dynamodb.updateItem({/*...*/}, function(err, data) {
// if you nest many callback you might end up in "callback hell"
});
});

The promise approach combined with async/await in v2 looks like this:

const AWS = require('aws-sdk');

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

async function demo() {}
const data = await dynamodb.getItem({/*...*/}).promise();
await dynamodb.updateItem({/*...*/}).promise();
}

demo()
.then(() => console.log('done'))
.catch(() => process.exit(1));

With the new v3 SDK, you can now write:

import { DynamoDB } from '@aws-sdk/client-dynamodb';

const dynamodb = new DynamoDB({apiVersion: '2012-08-10'});

async function demo() {}
const data = await dynamodb.getItem({/*...*/}); // no .promise() needed anymore!
await dynamodb.updateItem({/*...*/});
}

demo()
.then(() => console.log('done'))
.catch(() => process.exit(1));

This new feature is great for both frontend and backend developers.

Modularization & Tree Shaking

The v2 SDK packaged all AWS services. Over time, the aws-sdk module grew in size. And that’s a hard challenge if you use the SDK on the frontend. It was just too big and slowed down your website. Two features of the new v3 SDK will help:

  • Modularization
  • Tree shaking

Let me dive into both features.

Each AWS service is now packaged as its own npm module. You want to use DynamoDB, install the @aws-sdk/client-dynamodb package. Need some S3? Install @aws-sdk/client-s3 and so on.

JavaScript nowadays supports ES6 modules. Combined with tools like esbuild or webpack, we can eliminate the dead JS code that is “not used”. This is called tree shaking. If you want to benefit from tree shaking, don’t use the approach that is compatible with the v2 SDK:

import { DynamoDB } from '@aws-sdk/client-dynamodb';

const dynamodb = new DynamoDB({apiVersion: '2012-08-10'});

await dynamodb.getItem(/*...*/);

Instead, use:

import { DynamoDBClient, GetItemCommand } from '@aws-sdk/client-dynamodb';

const dynamodb = new DynamoDBClient({apiVersion: '2012-08-10'});
await client.send(new GetItemCommand(/*...*/));

Now, tree shaking can kick in and remove all the commands that you never use! Frontend developers will love it!

The Node.js Lambda runtime does not include the v3 SDK. If you want to keep your Lambda function code as small as possible, you should still use the v2 SDK because you don’t have to include it at all in your ZIP file.

The bad parts

  • X-Ray support missing (tracked here and here
  • As I said, the v3 SDK is not part of the Node.js AWS Lambda runtime. If you want to use it, you have to add it to your ZIP.
  • The DynamoDB DocumentClient is missing. Instead, you might want to use those utility functions. I never used the DocumentClient because I prefer the explicit over the implicit.
  • Client Side Monitoring (CSM) is not supported, which makes debugging IAM issues harder/impossible.

Additional features

  • If you want to write plugins for the AWS SDK (maybe because you add X-Ray support), you might be interested in the new middleware.
  • v3 is implemented in TypeScript. We also have types for the v2 SDK. Therefore, not a big change for us, the AWS customers.

AWS SDK for JavaScript v3 in Action

Watch the following video to learn how we use the new SDK in our Chatbot for AWS Monitoring.

Summary

Frontend developers should start using the v3 SDK today. Use command objects to tree shake away all of the unused code! For backend developers, I don’t see much benefit unless your code is paging a lot :) if your backend runs on Lambda, keep in mind that the v3 SDK is not part of the Lambda runtime! If you plan to migrate, check out the official migration guide.

Michael Wittig

Michael Wittig

I’ve been building on AWS since 2012 together with my brother Andreas. We are sharing our insights into all things AWS on cloudonaut and have written the book AWS in Action. Besides that, we’re currently working on bucketAV, HyperEnv for GitHub Actions, and marbot.

Here are the contact options for feedback and questions.