infra-platform-aws-sdk

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AWS SDK v3 Patterns

AWS SDK v3 使用模式

Quick Guide: AWS SDK v3 for JavaScript/TypeScript uses modular packages (
@aws-sdk/client-*
) with a command pattern: create a client, instantiate a command, call
client.send(command)
. Import only the services you need for tree-shaking. Use
DynamoDBDocumentClient
for native JS types. Use
getSignedUrl
from
@aws-sdk/s3-request-presigner
for presigned URLs. Handle errors with
instanceof
specific exception classes. Use built-in paginators (
paginate*
) with
for await...of
.

<critical_requirements>
快速指南: AWS SDK v3 for JavaScript/TypeScript采用模块化包(
@aws-sdk/client-*
)和命令模式:创建客户端、实例化命令、调用
client.send(command)
。仅导入所需服务以实现摇树优化。使用
DynamoDBDocumentClient
处理原生JS类型。使用
@aws-sdk/s3-request-presigner
中的
getSignedUrl
生成预签名URL。使用
instanceof
判断特定异常类来处理错误。结合
for await...of
使用内置分页器(
paginate*
)。

<critical_requirements>

CRITICAL: Before Using This Skill

重要提示:使用本技能前须知

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type
, named constants)
(You MUST use AWS SDK v3 modular packages (
@aws-sdk/client-*
) — NEVER the monolithic
aws-sdk
v2 package)
(You MUST use the command pattern:
client.send(new XxxCommand({...}))
— NEVER call methods directly on the client)
(You MUST use
DynamoDBDocumentClient
from
@aws-sdk/lib-dynamodb
for DynamoDB — it auto-marshalls native JS types)
(You MUST handle errors with
instanceof
specific exception classes — NEVER catch generic
Error
and check
.code
)
(You MUST use built-in paginators (
paginate*
functions) for paginated APIs — NEVER manually track continuation tokens)
</critical_requirements>

所有代码必须遵循CLAUDE.md中的项目约定(短横线命名、命名导出、导入顺序、
import type
、命名常量)
(必须使用AWS SDK v3的模块化包(
@aws-sdk/client-*
)——绝对禁止使用单体式的
aws-sdk
v2包)
(必须使用命令模式:
client.send(new XxxCommand({...}))
——绝对禁止直接调用客户端方法)
(必须使用
@aws-sdk/lib-dynamodb
中的
DynamoDBDocumentClient
操作DynamoDB——它会自动转换原生JS类型)
(必须使用
instanceof
判断特定异常类来处理错误——绝对禁止捕获通用
Error
并检查
.code
(必须使用内置分页器(
paginate*
函数)处理分页API——绝对禁止手动跟踪续传令牌)
</critical_requirements>

Examples

示例

  • Core Patterns — Client setup, S3 operations, DynamoDB basics, credential providers, error handling, pagination
  • Messaging — SQS send/receive/delete, SNS publish, FIFO queues, dead-letter patterns
  • Advanced — Lambda invocation, Secrets Manager, presigned URLs, middleware, streaming
  • Quick Reference — Package cheat sheet, import patterns, error handling decision tree, credential provider chain

Auto-detection: AWS SDK, @aws-sdk/client, S3Client, DynamoDBClient, DynamoDBDocumentClient, SQSClient, LambdaClient, SNSClient, SecretsManagerClient, PutObjectCommand, GetObjectCommand, GetCommand, PutCommand, QueryCommand, SendMessageCommand, InvokeCommand, GetSecretValueCommand, getSignedUrl, s3-request-presigner, credential-providers, fromEnv, fromIni, paginateListObjectsV2, aws-sdk-client-mock
When to use:
  • Interacting with any AWS service from TypeScript/JavaScript
  • S3 file operations (upload, download, presigned URLs, listings)
  • DynamoDB CRUD operations and queries
  • SQS message sending, receiving, and queue management
  • Lambda function invocation from other services
  • SNS topic publishing and notifications
  • Secrets Manager secret retrieval
  • Custom middleware for request/response modification
When NOT to use:
  • Infrastructure provisioning (use an IaC tool)
  • AWS console-only operations with no SDK equivalent
  • Simple CLI-only tasks better served by the AWS CLI directly
Key patterns covered:
  • Modular client setup with typed configuration
  • Command pattern (
    client.send(new Command({...}))
    )
  • S3: upload, download, delete, list, presigned URLs, streaming
  • DynamoDB:
    DynamoDBDocumentClient
    with
    Get
    ,
    Put
    ,
    Query
    ,
    Update
    ,
    Delete
  • SQS: send, receive, delete messages, long polling, FIFO
  • SNS: publish to topics, message attributes
  • Lambda: synchronous and asynchronous invocation
  • Secrets Manager: secret retrieval with caching
  • Credential provider chain and explicit providers
  • Error handling with
    instanceof
    exception classes and
    $metadata
  • Pagination with async iterators
  • Middleware stack customization
  • Retry configuration

<philosophy>
  • 核心模式 — 客户端配置、S3操作、DynamoDB基础、凭证提供器、错误处理、分页
  • 消息服务 — SQS发送/接收/删除、SNS发布、FIFO队列、死信队列模式
  • 进阶用法 — Lambda调用、Secrets Manager、预签名URL、中间件、流处理
  • 快速参考 — 包速查表、导入模式、错误处理决策树、凭证提供器链

自动检测关键词: AWS SDK, @aws-sdk/client, S3Client, DynamoDBClient, DynamoDBDocumentClient, SQSClient, LambdaClient, SNSClient, SecretsManagerClient, PutObjectCommand, GetObjectCommand, GetCommand, PutCommand, QueryCommand, SendMessageCommand, InvokeCommand, GetSecretValueCommand, getSignedUrl, s3-request-presigner, credential-providers, fromEnv, fromIni, paginateListObjectsV2, aws-sdk-client-mock
适用场景:
  • 通过TypeScript/JavaScript与任意AWS服务交互
  • S3文件操作(上传、下载、预签名URL、列表)
  • DynamoDB增删改查操作与查询
  • SQS消息发送、接收与队列管理
  • 从其他服务调用Lambda函数
  • SNS主题发布与通知
  • Secrets Manager密钥检索
  • 自定义中间件修改请求/响应
不适用场景:
  • 基础设施配置(使用IaC工具)
  • 仅AWS控制台支持且无SDK等效操作的功能
  • 更适合直接使用AWS CLI的简单CLI任务
涵盖的核心模式:
  • 带类型配置的模块化客户端设置
  • 命令模式(
    client.send(new Command({...}))
  • S3:上传、下载、删除、列表、预签名URL、流处理
  • DynamoDB:使用
    DynamoDBDocumentClient
    执行
    Get
    Put
    Query
    Update
    Delete
    操作
  • SQS:发送、接收、删除消息、长轮询、FIFO队列
  • SNS:主题发布、消息属性
  • Lambda:同步与异步调用
  • Secrets Manager:带缓存的密钥检索
  • 凭证提供器链与显式提供器
  • 使用
    instanceof
    异常类和
    $metadata
    处理错误
  • 异步迭代器分页
  • 中间件栈自定义
  • 重试配置

<philosophy>

Philosophy

设计理念

AWS SDK v3 is a ground-up rewrite of the v2 SDK for modern JavaScript/TypeScript. The core design principles:
  1. Modular packages — Each service is a separate npm package (
    @aws-sdk/client-s3
    ,
    @aws-sdk/client-dynamodb
    ). Import only what you use. This reduces bundle size by up to 90% compared to the monolithic v2
    aws-sdk
    package.
  2. Command pattern — Every API call is a Command object sent through a Client. This enables middleware, type safety, and testability. The client handles serialization, signing, retries, and deserialization.
  3. First-class TypeScript — Every command input and output is fully typed. Use the types to avoid runtime errors.
  4. Middleware stack — Customize request/response handling at various stages (serialize, build, finalize, deserialize) without monkey-patching.
  5. Built-in pagination — Paginator functions return async iterators, eliminating manual token tracking.
When to use AWS SDK v3:
  • Any server-side or serverless TypeScript/JavaScript that interacts with AWS services
  • Frontend applications that need direct AWS access (with appropriate auth)
  • Lambda functions (SDK v3 is included in Node.js 18+ Lambda runtimes)
When NOT to use:
  • Infrastructure provisioning and management (use an IaC tool)
  • One-off tasks better served by the AWS CLI
  • Languages other than JavaScript/TypeScript
</philosophy>
<patterns>
AWS SDK v3是针对现代JavaScript/TypeScript对v2 SDK进行的彻底重写。核心设计原则:
  1. 模块化包 — 每个服务都是独立的npm包(
    @aws-sdk/client-s3
    @aws-sdk/client-dynamodb
    )。仅导入所需内容。与单体式的v2
    aws-sdk
    包相比,这可将包大小减少多达90%。
  2. 命令模式 — 每个API调用都是通过客户端发送的Command对象。这支持中间件、类型安全和可测试性。客户端负责序列化、签名、重试和反序列化。
  3. 一等TypeScript支持 — 每个命令的输入和输出都完全类型化。使用类型避免运行时错误。
  4. 中间件栈 — 在各个阶段(序列化、构建、最终化、反序列化)自定义请求/响应处理,无需猴子补丁。
  5. 内置分页 — 分页器函数返回异步迭代器,消除手动令牌跟踪。
何时使用AWS SDK v3:
  • 任何与AWS服务交互的服务端或无服务器TypeScript/JavaScript应用
  • 需要直接访问AWS的前端应用(需配置适当权限)
  • Lambda函数(Node.js 18+ Lambda运行时已包含SDK v3)
何时不使用:
  • 基础设施配置与管理(使用IaC工具)
  • 更适合AWS CLI的一次性任务
  • JavaScript/TypeScript以外的语言
</philosophy>
<patterns>

Core Patterns

核心模式

Pattern 1: Client Setup and Command Pattern

模式1:客户端配置与命令模式

Every AWS service follows the same pattern: import the client and command, create a client instance, send the command.
typescript
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({ region: "us-east-1" });
await s3.send(
  new PutObjectCommand({
    Bucket: "my-bucket",
    Key: "data.json",
    Body: JSON.stringify({ hello: "world" }),
    ContentType: "application/json",
  }),
);
Why good: modular import keeps bundle small, command pattern enables middleware and type safety, region is explicit
Create clients once and reuse them — they manage connection pooling internally. In Lambda, create clients outside the handler for connection reuse across invocations.
See examples/core.md for client reuse patterns and configuration options.

每个AWS服务都遵循相同的模式:导入客户端和命令,创建客户端实例,发送命令。
typescript
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({ region: "us-east-1" });
await s3.send(
  new PutObjectCommand({
    Bucket: "my-bucket",
    Key: "data.json",
    Body: JSON.stringify({ hello: "world" }),
    ContentType: "application/json",
  }),
);
优势: 模块化导入减小包体积,命令模式支持中间件与类型安全,区域设置明确
客户端只需创建一次并复用——它们内部管理连接池。在Lambda中,在处理函数外创建客户端以跨调用复用连接。
查看examples/core.md了解客户端复用模式和配置选项。

Pattern 2: S3 Operations

模式2:S3操作

S3 is the most commonly used service. Key operations:
PutObject
,
GetObject
,
DeleteObject
,
ListObjectsV2
, and presigned URLs via
@aws-sdk/s3-request-presigner
.
typescript
import { GetObjectCommand, NoSuchKey } from "@aws-sdk/client-s3";

const response = await s3.send(
  new GetObjectCommand({
    Bucket: "my-bucket",
    Key: "data.json",
  }),
);
const body = await response.Body?.transformToString();
For presigned URLs, use the separate
@aws-sdk/s3-request-presigner
package:
typescript
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const PRESIGN_EXPIRY_SECONDS = 3_600;
const url = await getSignedUrl(
  s3,
  new GetObjectCommand({
    Bucket: "my-bucket",
    Key: "file.pdf",
  }),
  { expiresIn: PRESIGN_EXPIRY_SECONDS },
);
See examples/core.md for upload, download, delete, list, and streaming patterns.

S3是最常用的服务。关键操作包括:
PutObject
GetObject
DeleteObject
ListObjectsV2
,以及通过
@aws-sdk/s3-request-presigner
生成预签名URL。
typescript
import { GetObjectCommand, NoSuchKey } from "@aws-sdk/client-s3";

const response = await s3.send(
  new GetObjectCommand({
    Bucket: "my-bucket",
    Key: "data.json",
  }),
);
const body = await response.Body?.transformToString();
生成预签名URL需使用独立的
@aws-sdk/s3-request-presigner
包:
typescript
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const PRESIGN_EXPIRY_SECONDS = 3_600;
const url = await getSignedUrl(
  s3,
  new GetObjectCommand({
    Bucket: "my-bucket",
    Key: "file.pdf",
  }),
  { expiresIn: PRESIGN_EXPIRY_SECONDS },
);
查看examples/core.md了解上传、下载、删除、列表和流处理模式。

Pattern 3: DynamoDB with Document Client

模式3:使用Document Client操作DynamoDB

Use
DynamoDBDocumentClient
from
@aws-sdk/lib-dynamodb
— it automatically marshalls/unmarshalls between native JS types and DynamoDB's
AttributeValue
format.
typescript
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import {
  DynamoDBDocumentClient,
  GetCommand,
  PutCommand,
} from "@aws-sdk/lib-dynamodb";

const ddbDocClient = DynamoDBDocumentClient.from(new DynamoDBClient({}));

const { Item } = await ddbDocClient.send(
  new GetCommand({
    TableName: "users",
    Key: { userId: "abc-123" },
  }),
);
Why good: no manual
marshall()
/
unmarshall()
calls, native JS objects in and out, full type safety
Gotcha: Import commands from
@aws-sdk/lib-dynamodb
(not
@aws-sdk/client-dynamodb
) when using the document client — the lib-dynamodb commands accept native JS types.
See examples/core.md for Put, Query, Update, Delete, and batch operations.

使用
@aws-sdk/lib-dynamodb
中的
DynamoDBDocumentClient
——它会自动在原生JS类型与DynamoDB的
AttributeValue
格式之间进行转换。
typescript
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import {
  DynamoDBDocumentClient,
  GetCommand,
  PutCommand,
} from "@aws-sdk/lib-dynamodb";

const ddbDocClient = DynamoDBDocumentClient.from(new DynamoDBClient({}));

const { Item } = await ddbDocClient.send(
  new GetCommand({
    TableName: "users",
    Key: { userId: "abc-123" },
  }),
);
优势: 无需手动调用
marshall()
/
unmarshall()
,输入输出均为原生JS对象,完全类型安全
注意事项: 使用document client时,需从
@aws-sdk/lib-dynamodb
导入命令(而非
@aws-sdk/client-dynamodb
)——lib-dynamodb的命令支持原生JS类型。
查看examples/core.md了解Put、Query、Update、Delete和批量操作。

Pattern 4: Error Handling

模式4:错误处理

AWS SDK v3 errors extend service-specific base classes (e.g.,
S3ServiceException
). Use
instanceof
for typed error handling.
typescript
import {
  GetObjectCommand,
  NoSuchKey,
  S3ServiceException,
} from "@aws-sdk/client-s3";

try {
  await s3.send(new GetObjectCommand({ Bucket: "b", Key: "k" }));
} catch (error) {
  if (error instanceof NoSuchKey) {
    // Typed: error.name === "NoSuchKey", error.$metadata.httpStatusCode === 404
    return null;
  }
  if (error instanceof S3ServiceException) {
    // Any S3 service error — check error.$metadata.httpStatusCode
    throw error;
  }
  throw error; // Non-AWS error (network, etc.)
}
Why good:
instanceof
gives TypeScript type narrowing, exception classes are exported from the client package,
$metadata
provides HTTP status and request ID for debugging
See examples/core.md for the full error handling decision tree and retry patterns.

AWS SDK v3的错误继承自服务特定的基类(如
S3ServiceException
)。使用
instanceof
进行类型化错误处理。
typescript
import {
  GetObjectCommand,
  NoSuchKey,
  S3ServiceException,
} from "@aws-sdk/client-s3";

try {
  await s3.send(new GetObjectCommand({ Bucket: "b", Key: "k" }));
} catch (error) {
  if (error instanceof NoSuchKey) {
    // 类型化:error.name === "NoSuchKey", error.$metadata.httpStatusCode === 404
    return null;
  }
  if (error instanceof S3ServiceException) {
    // 任意S3服务错误——检查error.$metadata.httpStatusCode
    throw error;
  }
  throw error; // 非AWS错误(网络等)
}
优势:
instanceof
提供TypeScript类型收窄,异常类从客户端包导出,
$metadata
提供HTTP状态和请求ID用于调试
查看examples/core.md了解完整的错误处理决策树和重试模式。

Pattern 5: Pagination with Async Iterators

模式5:异步迭代器分页

Use built-in paginator functions for any paginated API. They return async iterators that handle continuation tokens automatically.
typescript
import { paginateListObjectsV2 } from "@aws-sdk/client-s3";

for await (const page of paginateListObjectsV2(
  { client: s3 },
  { Bucket: "my-bucket" },
)) {
  // page.Contents is an array of objects for this page
}
Why good: no manual token tracking, clean
for await...of
loop, handles all edge cases (empty pages, token format)
See examples/core.md for full S3 list, DynamoDB pagination, and good/bad comparison with manual token tracking.

对任何分页API使用内置分页器函数。它们返回自动处理续传令牌的异步迭代器。
typescript
import { paginateListObjectsV2 } from "@aws-sdk/client-s3";

for await (const page of paginateListObjectsV2(
  { client: s3 },
  { Bucket: "my-bucket" },
)) {
  // page.Contents是当前页的对象数组
}
优势: 无需手动跟踪令牌,简洁的
for await...of
循环,处理所有边缘情况(空页、令牌格式)
查看examples/core.md了解完整的S3列表、DynamoDB分页,以及与手动令牌跟踪的优劣对比。

Pattern 6: SQS Messaging

模式6:SQS消息服务

SQS uses
SendMessageCommand
,
ReceiveMessageCommand
, and
DeleteMessageCommand
. Always delete messages after processing.
typescript
import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";

const sqs = new SQSClient({});
await sqs.send(
  new SendMessageCommand({
    QueueUrl: QUEUE_URL,
    MessageBody: JSON.stringify({ orderId: "order-123" }),
  }),
);
See examples/messaging.md for receive/delete, long polling, FIFO queues, and dead-letter patterns.

SQS使用
SendMessageCommand
ReceiveMessageCommand
DeleteMessageCommand
。处理完成后务必删除消息。
typescript
import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";

const sqs = new SQSClient({});
await sqs.send(
  new SendMessageCommand({
    QueueUrl: QUEUE_URL,
    MessageBody: JSON.stringify({ orderId: "order-123" }),
  }),
);
查看examples/messaging.md了解接收/删除、长轮询、FIFO队列和死信队列模式。

Pattern 7: SNS Publishing

模式7:SNS发布

SNS publishes messages to topics. Subscribers receive messages on their configured endpoints.
typescript
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";

const sns = new SNSClient({});
await sns.send(
  new PublishCommand({
    TopicArn: TOPIC_ARN,
    Message: JSON.stringify({ event: "order.created", orderId: "order-123" }),
    MessageAttributes: {
      eventType: { DataType: "String", StringValue: "order.created" },
    },
  }),
);
See examples/messaging.md for topic management and message filtering.

SNS向主题发布消息。订阅者通过配置的端点接收消息。
typescript
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";

const sns = new SNSClient({});
await sns.send(
  new PublishCommand({
    TopicArn: TOPIC_ARN,
    Message: JSON.stringify({ event: "order.created", orderId: "order-123" }),
    MessageAttributes: {
      eventType: { DataType: "String", StringValue: "order.created" },
    },
  }),
);
查看examples/messaging.md了解主题管理和消息过滤。

Pattern 8: Lambda Invocation and Secrets Manager

模式8:Lambda调用与Secrets Manager

Invoke Lambda functions synchronously or asynchronously. Retrieve secrets from Secrets Manager with caching.
typescript
import { LambdaClient, InvokeCommand } from "@aws-sdk/client-lambda";

const lambda = new LambdaClient({});
const response = await lambda.send(
  new InvokeCommand({
    FunctionName: "process-order",
    InvocationType: "RequestResponse", // synchronous
    Payload: JSON.stringify({ orderId: "order-123" }),
  }),
);
const result = JSON.parse(new TextDecoder().decode(response.Payload));
See examples/advanced.md for async invocation, Secrets Manager retrieval, and caching patterns.
</patterns>
<decision_framework>
同步或异步调用Lambda函数。从Secrets Manager检索密钥并缓存。
typescript
import { LambdaClient, InvokeCommand } from "@aws-sdk/client-lambda";

const lambda = new LambdaClient({});
const response = await lambda.send(
  new InvokeCommand({
    FunctionName: "process-order",
    InvocationType: "RequestResponse", // 同步
    Payload: JSON.stringify({ orderId: "order-123" }),
  }),
);
const result = JSON.parse(new TextDecoder().decode(response.Payload));
查看examples/advanced.md了解异步调用、Secrets Manager检索和缓存模式。
</patterns>
<decision_framework>

Decision Framework

决策框架

Choosing the Right DynamoDB Client

选择合适的DynamoDB客户端

Are you working with DynamoDB?
  |
  +-- Need native JS objects (recommended) --> DynamoDBDocumentClient from @aws-sdk/lib-dynamodb
  |     +-- Import Get/Put/Query/Update/Delete Commands from @aws-sdk/lib-dynamodb
  |
  +-- Need raw AttributeValue format --> DynamoDBClient from @aws-sdk/client-dynamodb
        +-- Import commands from @aws-sdk/client-dynamodb
        +-- Manually marshall/unmarshall with @aws-sdk/util-dynamodb
你是否在使用DynamoDB?
  |
  +-- 需要原生JS对象(推荐) --> 使用@aws-sdk/lib-dynamodb中的DynamoDBDocumentClient
  |     +-- 从@aws-sdk/lib-dynamodb导入Get/Put/Query/Update/Delete命令
  |
  +-- 需要原始AttributeValue格式 --> 使用@aws-sdk/client-dynamodb中的DynamoDBClient
        +-- 从@aws-sdk/client-dynamodb导入命令
        +-- 使用@aws-sdk/util-dynamodb手动转换

Choosing Between Synchronous and Async Lambda Invocation

选择同步或异步Lambda调用

Do you need the Lambda response immediately?
  |
  +-- YES --> InvocationType: "RequestResponse" (synchronous, waits for result)
  |
  +-- NO  --> InvocationType: "Event" (async, returns immediately, 3 retries)
你是否需要立即获取Lambda响应?
  |
  +-- 是 --> InvocationType: "RequestResponse"(同步,等待结果)
  |
  +-- 否 --> InvocationType: "Event"(异步,立即返回,重试3次)

Credential Provider Selection

凭证提供器选择

Where is this code running?
  |
  +-- Lambda / ECS / EC2 --> Default chain (auto-detects IAM role) — no config needed
  |
  +-- Local development --> fromIni() (reads ~/.aws/credentials) or fromEnv()
  |
  +-- CI/CD pipeline --> fromEnv() with AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY
  |
  +-- Cross-account access --> fromTemporaryCredentials() with STS AssumeRole
</decision_framework>

<red_flags>
代码运行环境?
  |
  +-- Lambda / ECS / EC2 --> 默认链(自动检测IAM角色)——无需配置
  |
  +-- 本地开发 --> fromIni()(读取~/.aws/credentials)或fromEnv()
  |
  +-- CI/CD流水线 --> fromEnv()配合AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY
  |
  +-- 跨账号访问 --> fromTemporaryCredentials()配合STS AssumeRole
</decision_framework>

<red_flags>

RED FLAGS

注意事项(红色警告)

High Priority Issues:
  • Using the monolithic
    aws-sdk
    v2 package — it ships the entire SDK (~70 MB). Use modular
    @aws-sdk/client-*
    packages.
  • Calling methods directly on the client (v2 style:
    s3.getObject()
    ) — use the command pattern:
    s3.send(new GetObjectCommand({...}))
    .
  • Using raw
    DynamoDBClient
    commands with manual
    marshall()
    /
    unmarshall()
    — use
    DynamoDBDocumentClient
    from
    @aws-sdk/lib-dynamodb
    .
  • Catching errors with
    .code
    string comparison (v2 style) — use
    instanceof
    with typed exception classes.
  • Manually tracking pagination tokens in a while loop — use built-in
    paginate*
    functions with
    for await...of
    .
  • Hardcoding AWS credentials in source code — use the credential provider chain or environment variables.
Medium Priority Issues:
  • Creating a new client instance per request — create clients once and reuse them (they manage connection pooling).
  • Not setting a region explicitly — defaults vary by environment and cause confusing errors.
  • Mixing
    @aws-sdk/client-dynamodb
    and
    @aws-sdk/lib-dynamodb
    command imports — pick one approach per codebase.
  • Missing
    ContentType
    on S3
    PutObject
    — S3 defaults to
    application/octet-stream
    , breaking browser downloads.
  • Not buffering the S3
    GetObject
    response body —
    response.Body
    is a stream; call
    .transformToString()
    or
    .transformToByteArray()
    .
Gotchas and Edge Cases:
  • GetObject
    response body is a
    ReadableStream
    (not a string) — you must consume it with
    .transformToString()
    ,
    .transformToByteArray()
    , or pipe it to a writable stream.
  • DynamoDBDocumentClient
    commands come from
    @aws-sdk/lib-dynamodb
    , NOT
    @aws-sdk/client-dynamodb
    — importing from the wrong package gives you raw
    AttributeValue
    types.
  • Presigned URLs require the separate
    @aws-sdk/s3-request-presigner
    package — it is NOT included in
    @aws-sdk/client-s3
    .
  • InvokeCommand
    returns
    Payload
    as a
    Uint8Array
    — decode with
    new TextDecoder().decode(response.Payload)
    before
    JSON.parse
    .
  • SDK v3 version mismatches across client packages cause TypeScript errors — pin all
    @aws-sdk/*
    packages to the same version range.
  • In Lambda, the SDK is bundled in the runtime but may be outdated — bundle your own version for latest features.
  • SQS ReceiveMessageCommand
    may return
    Messages: undefined
    (not empty array) when no messages are available — always use
    response.Messages ?? []
    .
  • Presigned URL expiry is capped at 7 days, but temporary credentials may expire sooner — the URL stops working when the signing credentials expire.
</red_flags>

<critical_reminders>
高优先级问题:
  • 使用单体式
    aws-sdk
    v2包——它包含整个SDK(约70 MB)。请使用模块化
    @aws-sdk/client-*
    包。
  • 直接调用客户端方法(v2风格:
    s3.getObject()
    )——请使用命令模式:
    s3.send(new GetObjectCommand({...}))
  • 使用原始
    DynamoDBClient
    命令并手动调用
    marshall()
    /
    unmarshall()
    ——请使用
    @aws-sdk/lib-dynamodb
    中的
    DynamoDBDocumentClient
  • 通过
    .code
    字符串比较捕获错误(v2风格)——请使用
    instanceof
    配合类型化异常类。
  • 在while循环中手动跟踪分页令牌——请使用内置
    paginate*
    函数配合
    for await...of
  • 在源代码中硬编码AWS凭证——请使用凭证提供器链或环境变量。
中优先级问题:
  • 每个请求创建新的客户端实例——客户端只需创建一次并复用(它们管理连接池)。
  • 未显式设置区域——默认值因环境而异,会导致混淆性错误。
  • 混合导入
    @aws-sdk/client-dynamodb
    @aws-sdk/lib-dynamodb
    的命令——每个代码库选择一种方式。
  • S3
    PutObject
    未设置
    ContentType
    ——S3默认使用
    application/octet-stream
    ,会破坏浏览器下载。
  • 未缓冲S3
    GetObject
    响应体——
    response.Body
    是流;需调用
    .transformToString()
    .transformToByteArray()
注意事项与边缘情况:
  • GetObject
    响应体是
    ReadableStream
    (而非字符串)——必须通过
    .transformToString()
    .transformToByteArray()
    或管道到可写流来消费。
  • DynamoDBDocumentClient
    命令来自
    @aws-sdk/lib-dynamodb
    ,而非
    @aws-sdk/client-dynamodb
    ——从错误的包导入会得到原始
    AttributeValue
    类型。
  • 生成预签名URL需要独立的
    @aws-sdk/s3-request-presigner
    包——它不包含在
    @aws-sdk/client-s3
    中。
  • InvokeCommand
    返回的
    Payload
    Uint8Array
    ——
    JSON.parse
    前需使用
    new TextDecoder().decode(response.Payload)
    解码。
  • 客户端包之间的SDK v3版本不匹配会导致TypeScript错误——将所有
    @aws-sdk/*
    包固定到相同版本范围。
  • 在Lambda中,运行时已包含SDK但可能过时——如需最新功能,请自行打包版本。
  • SQS ReceiveMessageCommand
    在无消息时可能返回
    Messages: undefined
    (而非空数组)——请始终使用
    response.Messages ?? []
  • 预签名URL的有效期上限为7天,但临时凭证可能更早过期——签名凭证过期后URL将失效。
</red_flags>

<critical_reminders>

CRITICAL REMINDERS

重要提醒

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type
, named constants)
(You MUST use AWS SDK v3 modular packages (
@aws-sdk/client-*
) — NEVER the monolithic
aws-sdk
v2 package)
(You MUST use the command pattern:
client.send(new XxxCommand({...}))
— NEVER call methods directly on the client)
(You MUST use
DynamoDBDocumentClient
from
@aws-sdk/lib-dynamodb
for DynamoDB — it auto-marshalls native JS types)
(You MUST handle errors with
instanceof
specific exception classes — NEVER catch generic
Error
and check
.code
)
(You MUST use built-in paginators (
paginate*
functions) for paginated APIs — NEVER manually track continuation tokens)
Failure to follow these rules will cause bloated bundles (v2), lost type safety (direct calls), marshalling bugs (raw DynamoDB), and fragile error handling (string comparison).
</critical_reminders>
所有代码必须遵循CLAUDE.md中的项目约定(短横线命名、命名导出、导入顺序、
import type
、命名常量)
(必须使用AWS SDK v3的模块化包(
@aws-sdk/client-*
)——绝对禁止使用单体式的
aws-sdk
v2包)
(必须使用命令模式:
client.send(new XxxCommand({...}))
——绝对禁止直接调用客户端方法)
(必须使用
@aws-sdk/lib-dynamodb
中的
DynamoDBDocumentClient
操作DynamoDB——它会自动转换原生JS类型)
(必须使用
instanceof
判断特定异常类来处理错误——绝对禁止捕获通用
Error
并检查
.code
(必须使用内置分页器(
paginate*
函数)处理分页API——绝对禁止手动跟踪续传令牌)
不遵循这些规则会导致包体积臃肿(v2)、丢失类型安全(直接调用)、转换错误(原始DynamoDB)和脆弱的错误处理(字符串比较)。
</critical_reminders>