Skip to content

Commit f77c77f

Browse files
authored
docs: add supplemental doc on AWS Lambda usage (#5807)
1 parent b1c821a commit f77c77f

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

supplemental-docs/AWS_LAMBDA.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Using the AWS SDK for JavaScript (v3) on AWS Lambda Node.js runtimes
2+
3+
## AWS Lambda provided AWS SDK
4+
5+
Several AWS Lambda runtimes, including those for Node.js, include the AWS SDK at various versions.
6+
7+
The SDK is provided as a convenience for development. For greater control of the SDK version and its runtime characteristics such as
8+
JavaScript bundling, upload your selection of the AWS SDK as part of your function code.
9+
10+
To check the version of the SDK that is installed, you can log the package.json metadata of a package that you are using.
11+
12+
```js
13+
// Example: discovering the installed AWS SDK version.
14+
const pkgJson = require("@aws-sdk/client-s3/package.json");
15+
16+
exports.handler = function (event) {
17+
console.log(pkgJson);
18+
return JSON.stringify(pkgJson);
19+
}
20+
```
21+
22+
## Best practices for initializing AWS SDK Clients in AWS Lambda
23+
24+
Suppose that you have an `async` function called, for example `prepare`, that you need to initialize only once.
25+
You do not want to execute it for every function invocation.
26+
27+
```js
28+
// Example: one-time initialization in the handler code path.
29+
30+
import { DynamoDB } from "@aws-sdk/client-dynamodb";
31+
32+
async function prepare() {
33+
// do one-time setup, fetch credentials, secrets, initialize SDK clients, etc.
34+
}
35+
36+
export async function handler(event) {
37+
// ...
38+
}
39+
```
40+
41+
You may be tempted to call this function outside the handler like so:
42+
43+
```js
44+
// Example: call prepare outside of handler.
45+
46+
const ready = prepare();
47+
48+
export async function handler(event) {
49+
await ready;
50+
// ...
51+
}
52+
```
53+
54+
There is a potential complication with this style. This is a peculiarity of AWS Lambda's cold/warm states and provisioned concurrency.
55+
If you make network requests in the `prepare()` function, they may be frozen pre-flight as part of early provisioning. In a certain
56+
edge case, time-sensitive signed requests may become invalid due to the delay between provisioning and execution.
57+
58+
Therefore, we recommend that you perform one-time setup inside the handler. This does **not** mean that you need
59+
to execute the preparation code redundantly. Here is how:
60+
61+
```js
62+
// Example: call prepare inside handler, but only once.
63+
64+
let ready = false;
65+
66+
export async function handler(event) {
67+
if (!ready) {
68+
await prepare(); ready = true;
69+
}
70+
// ...
71+
}
72+
```
73+
74+
A more practical example:
75+
76+
```ts
77+
import { fromTemporaryCredentials } from "@aws-sdk/credential-providers";
78+
import { DynamoDB } from "@aws-sdk/client-dynamodb";
79+
80+
async function prepare() {
81+
const credentials = fromTemporaryCredentials({})();
82+
const dynamodb = new DynamoDB({ credentials });
83+
return dynamodb;
84+
}
85+
86+
let client: DynamoDB | null = null;
87+
88+
export async function handler(event) {
89+
if (!client) client = await prepare();
90+
91+
return client.getItem({
92+
TableName: "my-table",
93+
Key: { id: { S: "1" } },
94+
});
95+
}
96+
```

0 commit comments

Comments
 (0)