March 14, 2021 / 5 minutes / #AWS #DynamoDB #NoSQL #GraphQL #Serverless
In December 2020, AWS released AWS SDK v3 for Javascript. It promises to be modular and has a more tree-shakeable structure, resulting in smaller artifact sizes. This is especially important if you're interacting with AWS resources inside Lambda functions where each KB of code affects your cold-start time and 💸. Unfortunately, migration isn't straightforward. The signature of new V3 calls is new - some functions are gone, and some are replaced with new modules.
In this blog post, I show upgrading strategies from AWS SDK V2 to V3 for a few most common use cases in Serverless, at least for me. Official docs are describing three migration paths, but for the purpose of this article, we'll focus only on the 3rd Path - the proper one using the Command objects and fully async/await
based approach.
The most frequent complaint regarding the new DynamoDB client from AWS SDK V3 was a lack of DocumentClient
library. Instead, we were forced to call marshall()
/ unmarshall()
whenever inserting, putting or getting items from DynamoDB. This was introducing a lot of unnecessary complexity and caused code to be harder to follow and test.
Fortunately, AWS DynamoDB Document Client has been recently added to the V3.
In V2, once we had our DocumentClient
constructed, interaction with DynamoDB in Node.js was boiling down to using methods like get
, put
, scan
or query
and ending them with .promise()
call.
In V3, DocumentClient
is imported from a different package and created using DynamoDBDocumentClient.from()
method.
Moreover, you can call the document client operations using Command objects.
If you don't like this new style, you can still use the old .put()
method too. However, in this case, you need to import DynamoDBDocument
instead of DynamoDBDocumentClient
.
Interacting with Simple Storage from Lambdas is a widespread pattern. Let's talk about uploading, downloading, and preparing pre-signed URLs.
The complexity of uploading large files to S3 in V2 is hidden inside the upload
method. It takes care of initiating the multipart upload, uploading parts, and calculating checksums. There's also a famous .promise()
call at the end to promisify the call.
In V3, we are not only forced to import SDK in a modular way, but also we have to import two packages: client-s3
- responsible for communicating with AWS S3, and lib-storage
, which is a high-level helper library containing classes like Upload
which now take care of multipart upload orchestration.
Pre-signed URLs are useful when you need to expose some data to the client in a secure way or allow them to upload files from the client directly to the S3. In such a scenario, the client requests a backend for a pre-signed URL, the backend sends it back to the client, and the client initiates uploading procedure to the S3 directly using provided URL.
In V2, you had two options to generate pre-signed URLs - synchronously and asynchronously.
In V3, there's only one option - asynchronous one. Moreover, it requires you to import @aws-sdk/s3-request-presigner
package and call getSignedUrl
using the client and the Command object.
Even though invoking functions from functions is considered as an antipattern by some, I believe that's not the case if you know what you're doing.
In V2, invoking Lambda asynchronously or synchronously required just the FunctionName
parameters. Optional params like LogType: 'Tail'
are helpful if we want to forward up to 4KB of logs from the invoked Lambda to the caller.
In V3, the signature is almost identical. The difference is in the Payload
parameter. While V2 accepted string
, V3 accepts only Uint8Array
. Since in Node.js Buffer
instances are also Uint8Array
instances, we can use them instead.
Up to version 3.7.0, using SSO credentials was impossible. The workaround was to copy & paste credentials provided by the SSO as environment variables. Luckily, this issue is now solved.
As I'm writing this, AWS SDK V3 is not working correctly with X-Ray, which is a showstopper for many of us. This is due to the new middleware architecture, which is incompatible with how the X-Ray SDK hooks into the version 2.x. But, there's a pull request already reviewed as ☑️, waiting to be merged
ChainableTemporaryCredentials
Currently, AWS SDK V3 is not supporting this. This is especially useful in multi-tenant SaaS environments where your Lambdas/Containers/VMs have to assume a dynamic role-based on runtime input/context.
In V2, there was this famous Keep-Alive trick which forced AWS SDK to reuse HTTP connections. This reduced the number of HTTP handshakes performed and improved overall Lambda performance. In V3, this is happening automatically.
-- Written by Rafal Wilinski. Founder of Dynobase - Professional GUI Client for DynamoDB