aws-lambda-typescript-integration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AWS Lambda TypeScript Integration

AWS Lambda TypeScript集成方案

Patterns for creating high-performance AWS Lambda functions in TypeScript with optimized cold starts.
本文提供了创建高性能TypeScript版AWS Lambda函数的模式,包含冷启动优化方案。

Overview

概述

This skill provides complete patterns for AWS Lambda TypeScript development, covering two main approaches:
  1. NestJS Framework - Full-featured framework with dependency injection, modular architecture, and extensive ecosystem
  2. Raw TypeScript - Minimal overhead approach with maximum control and smaller bundle size
Both approaches support API Gateway and ALB integration with production-ready configurations.
本技能提供了AWS Lambda TypeScript开发的完整模式,涵盖两种主要方案:
  1. NestJS框架 - 功能完善的框架,具备依赖注入、模块化架构和丰富的生态系统
  2. 原生TypeScript - 开销极小的方案,拥有最大控制权和更小的包体积
两种方案均支持API Gateway和ALB集成,且配置可直接用于生产环境。

When to Use

适用场景

Use this skill when:
  • Creating new Lambda functions in TypeScript
  • Migrating existing TypeScript applications to Lambda
  • Optimizing cold start performance for TypeScript Lambda
  • Choosing between framework-based and minimal TypeScript approaches
  • Configuring API Gateway or ALB integration
  • Setting up deployment pipelines for TypeScript Lambda
在以下场景中使用本技能:
  • 创建新的TypeScript版Lambda函数
  • 将现有TypeScript应用迁移至Lambda
  • 优化TypeScript Lambda的冷启动性能
  • 在基于框架的方案与轻量TypeScript方案间做选择
  • 配置API Gateway或ALB集成
  • 为TypeScript Lambda设置部署流水线

Instructions

操作步骤

1. Choose Your Approach

1. 选择方案

ApproachCold StartBundle SizeBest ForComplexity
NestJS< 500msLarger (100KB+)Complex APIs, enterprise apps, DI neededMedium
Raw TypeScript< 100msSmaller (< 50KB)Simple handlers, microservices, minimal depsLow
方案冷启动时间包体积最佳适用场景复杂度
NestJS< 500毫秒较大(100KB+)复杂API、企业级应用、需要依赖注入中等
原生TypeScript< 100毫秒较小(< 50KB)简单处理器、微服务、依赖极少

2. Project Structure

2. 项目结构

NestJS Structure

NestJS项目结构

my-nestjs-lambda/
├── src/
│   ├── app.module.ts
│   ├── main.ts
│   ├── lambda.ts           # Lambda entry point
│   └── modules/
│       └── api/
├── package.json
├── tsconfig.json
└── serverless.yml
my-nestjs-lambda/
├── src/
│   ├── app.module.ts
│   ├── main.ts
│   ├── lambda.ts           # Lambda入口文件
│   └── modules/
│       └── api/
├── package.json
├── tsconfig.json
└── serverless.yml

Raw TypeScript Structure

原生TypeScript项目结构

my-ts-lambda/
├── src/
│   ├── handlers/
│   │   └── api.handler.ts
│   ├── services/
│   └── utils/
├── dist/                   # Compiled output
├── package.json
├── tsconfig.json
└── template.yaml
my-ts-lambda/
├── src/
│   ├── handlers/
│   │   └── api.handler.ts
│   ├── services/
│   └── utils/
├── dist/                   # 编译输出目录
├── package.json
├── tsconfig.json
└── template.yaml

3. Implementation Examples

3. 实现示例

See the References section for detailed implementation guides. Quick examples:
NestJS Handler:
typescript
// lambda.ts
import { NestFactory } from '@nestjs/core';
import { ExpressAdapter } from '@nestjs/platform-express';
import serverlessExpress from '@codegenie/serverless-express';
import { Context, Handler } from 'aws-lambda';
import express from 'express';
import { AppModule } from './src/app.module';

let cachedServer: Handler;

async function bootstrap(): Promise<Handler> {
  const expressApp = express();
  const adapter = new ExpressAdapter(expressApp);
  const nestApp = await NestFactory.create(AppModule, adapter);
  await nestApp.init();
  return serverlessExpress({ app: expressApp });
}

export const handler: Handler = async (event: any, context: Context) => {
  if (!cachedServer) {
    cachedServer = await bootstrap();
  }
  return cachedServer(event, context);
};
Raw TypeScript Handler:
typescript
// src/handlers/api.handler.ts
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';

export const handler = async (
  event: APIGatewayProxyEvent,
  context: Context
): Promise<APIGatewayProxyResult> => {
  return {
    statusCode: 200,
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ message: 'Hello from TypeScript Lambda!' })
  };
};
详细的实现指南请参考参考资料章节。以下是快速示例:
NestJS处理器:
typescript
// lambda.ts
import { NestFactory } from '@nestjs/core';
import { ExpressAdapter } from '@nestjs/platform-express';
import serverlessExpress from '@codegenie/serverless-express';
import { Context, Handler } from 'aws-lambda';
import express from 'express';
import { AppModule } from './src/app.module';

let cachedServer: Handler;

async function bootstrap(): Promise<Handler> {
  const expressApp = express();
  const adapter = new ExpressAdapter(expressApp);
  const nestApp = await NestFactory.create(AppModule, adapter);
  await nestApp.init();
  return serverlessExpress({ app: expressApp });
}

export const handler: Handler = async (event: any, context: Context) => {
  if (!cachedServer) {
    cachedServer = await bootstrap();
  }
  return cachedServer(event, context);
};
原生TypeScript处理器:
typescript
// src/handlers/api.handler.ts
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';

export const handler = async (
  event: APIGatewayProxyEvent,
  context: Context
): Promise<APIGatewayProxyResult> => {
  return {
    statusCode: 200,
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ message: 'Hello from TypeScript Lambda!' })
  };
};

Core Concepts

核心概念

Cold Start Optimization

冷启动优化

TypeScript cold start depends on bundle size and initialization code. Key strategies:
  1. Lazy Loading - Defer heavy imports until needed
  2. Tree Shaking - Remove unused code from bundle
  3. Minification - Use esbuild or terser for smaller bundles
  4. Instance Caching - Cache initialized services between invocations
See Raw TypeScript Lambda for detailed patterns.
TypeScript的冷启动时间取决于包体积和初始化代码。关键策略:
  1. 懒加载 - 将重量级导入延迟到需要时再加载
  2. 摇树优化 - 从包中移除未使用的代码
  3. 代码压缩 - 使用esbuild或terser来减小包体积
  4. 实例缓存 - 在多次调用之间缓存已初始化的服务
详细模式请参考原生TypeScript Lambda

Connection Management

连接管理

Create clients at module level and reuse:
typescript
// GOOD: Initialize once, reuse across invocations
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';

const dynamoClient = new DynamoDBClient({ region: process.env.AWS_REGION });

export const handler = async (event: APIGatewayProxyEvent) => {
  // Use dynamoClient - already initialized
};
在模块级别创建客户端并复用:
typescript
// 推荐:初始化一次,在多次调用之间复用
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';

const dynamoClient = new DynamoDBClient({ region: process.env.AWS_REGION });

export const handler = async (event: APIGatewayProxyEvent) => {
  // 使用dynamoClient - 已完成初始化
};

Environment Configuration

环境配置

typescript
// src/config/env.config.ts
export const env = {
  region: process.env.AWS_REGION || 'us-east-1',
  tableName: process.env.TABLE_NAME || '',
  debug: process.env.DEBUG === 'true',
};

// Validate required variables
if (!env.tableName) {
  throw new Error('TABLE_NAME environment variable is required');
}
typescript
// src/config/env.config.ts
export const env = {
  region: process.env.AWS_REGION || 'us-east-1',
  tableName: process.env.TABLE_NAME || '',
  debug: process.env.DEBUG === 'true',
};

// 验证必填变量
if (!env.tableName) {
  throw new Error('TABLE_NAME环境变量为必填项');
}

Best Practices

最佳实践

Memory and Timeout Configuration

内存与超时配置

  • Memory: Start with 512MB for NestJS, 256MB for raw TypeScript
  • Timeout: Set based on cold start + expected processing time
    • NestJS: 10-30 seconds for cold start buffer
    • Raw TypeScript: 3-10 seconds typically sufficient
  • 内存:NestJS初始设置为512MB,原生TypeScript初始设置为256MB
  • 超时:根据冷启动时间 + 预期处理时间设置
    • NestJS:预留10-30秒的冷启动缓冲时间
    • 原生TypeScript:通常3-10秒足够

Dependencies

依赖管理

Keep
package.json
minimal:
json
{
  "dependencies": {
    "aws-lambda": "^3.1.0",
    "@aws-sdk/client-dynamodb": "^3.450.0"
  },
  "devDependencies": {
    "typescript": "^5.3.0",
    "esbuild": "^0.19.0"
  }
}
保持
package.json
简洁:
json
{
  "dependencies": {
    "aws-lambda": "^3.1.0",
    "@aws-sdk/client-dynamodb": "^3.450.0"
  },
  "devDependencies": {
    "typescript": "^5.3.0",
    "esbuild": "^0.19.0"
  }
}

Error Handling

错误处理

Return proper HTTP codes with structured errors:
typescript
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
  try {
    const result = await processEvent(event);
    return {
      statusCode: 200,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(result)
    };
  } catch (error) {
    console.error('Error processing request:', error);
    return {
      statusCode: 500,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ error: 'Internal server error' })
    };
  }
};
返回标准HTTP状态码和结构化错误:
typescript
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
  try {
    const result = await processEvent(event);
    return {
      statusCode: 200,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(result)
    };
  } catch (error) {
    console.error('处理请求时出错:', error);
    return {
      statusCode: 500,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ error: '内部服务器错误' })
    };
  }
};

Logging

日志记录

Use structured logging for CloudWatch Insights:
typescript
const log = (level: string, message: string, meta?: object) => {
  console.log(JSON.stringify({
    level,
    message,
    timestamp: new Date().toISOString(),
    ...meta
  }));
};

log('info', 'Request processed', { requestId: context.awsRequestId });
使用结构化日志以便于CloudWatch Insights分析:
typescript
const log = (level: string, message: string, meta?: object) => {
  console.log(JSON.stringify({
    level,
    message,
    timestamp: new Date().toISOString(),
    ...meta
  }));
};

log('info', '请求处理完成', { requestId: context.awsRequestId });

Deployment Options

部署选项

Quick Start

快速开始

Serverless Framework:
yaml
service: my-typescript-api

provider:
  name: aws
  runtime: nodejs20.x

functions:
  api:
    handler: dist/handler.handler
    events:
      - http:
          path: /{proxy+}
          method: ANY
AWS SAM:
yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  ApiFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: dist/
      Handler: handler.handler
      Runtime: nodejs20.x
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: ANY
For complete deployment configurations including CI/CD, see Serverless Deployment.
Serverless Framework:
yaml
service: my-typescript-api

provider:
  name: aws
  runtime: nodejs20.x

functions:
  api:
    handler: dist/handler.handler
    events:
      - http:
          path: /{proxy+}
          method: ANY
AWS SAM:
yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  ApiFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: dist/
      Handler: handler.handler
      Runtime: nodejs20.x
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: ANY
包含CI/CD的完整部署配置请参考无服务器部署

Constraints and Warnings

约束与注意事项

Lambda Limits

Lambda限制

  • Deployment package: 250MB unzipped maximum (50MB zipped)
  • Memory: 128MB to 10GB
  • Timeout: 15 minutes maximum
  • Concurrent executions: 1000 default (adjustable)
  • Environment variables: 4KB total size
  • 部署包:最大250MB未压缩(压缩后50MB)
  • 内存:128MB至10GB
  • 超时:最大15分钟
  • 并发执行数:默认1000(可调整)
  • 环境变量:总大小4KB

TypeScript-Specific Considerations

TypeScript特定注意事项

  • Bundle size: TypeScript compiles to JavaScript; use bundlers to minimize size
  • Cold start: Node.js 20.x offers best performance
  • Dependencies: Use Lambda Layers for shared dependencies
  • Native modules: Must be compiled for Amazon Linux 2
  • 包体积:TypeScript编译为JavaScript;使用打包工具最小化体积
  • 冷启动:Node.js 20.x性能最佳
  • 依赖:使用Lambda Layers管理共享依赖
  • 原生模块:必须为Amazon Linux 2编译

Common Pitfalls

常见陷阱

  1. Importing heavy libraries at module level - Defer to lazy loading if not always needed
  2. Not bundling dependencies - Include all production dependencies in the package
  3. Missing type definitions - Install
    @types/aws-lambda
    for proper event typing
  4. No timeout handling - Use
    context.getRemainingTimeInMillis()
    for long operations
  1. 在模块级别导入重量级库 - 如果不是始终需要,延迟到懒加载
  2. 未打包依赖 - 包中需包含所有生产依赖
  3. 缺少类型定义 - 安装
    @types/aws-lambda
    以获得正确的事件类型
  4. 未处理超时 - 对于长时间操作,使用
    context.getRemainingTimeInMillis()

Security Considerations

安全注意事项

  • Never hardcode credentials; use IAM roles and environment variables
  • Validate all input data
  • Use least privilege IAM policies
  • Enable CloudTrail for audit logging
  • Sanitize logs to avoid leaking sensitive data
  • 切勿硬编码凭证;使用IAM角色和环境变量
  • 验证所有输入数据
  • 使用最小权限原则配置IAM策略
  • 启用CloudTrail进行审计日志记录
  • 清理日志以避免泄露敏感数据

References

参考资料

For detailed guidance on specific topics:
  • NestJS Lambda - Complete NestJS setup, dependency injection, Express/Fastify adapters
  • Raw TypeScript Lambda - Minimal handler patterns, bundling, tree shaking
  • Serverless Config - Serverless Framework and SAM configuration
  • Serverless Deployment - CI/CD pipelines, environment management
  • Testing - Jest, integration testing, SAM Local
特定主题的详细指南:
  • NestJS Lambda - 完整NestJS设置、依赖注入、Express/Fastify适配器
  • 原生TypeScript Lambda - 轻量处理器模式、打包、摇树优化
  • 无服务器配置 - Serverless Framework和SAM配置
  • 无服务器部署 - CI/CD流水线、环境管理
  • 测试 - Jest、集成测试、SAM Local

Examples

示例

Example 1: Create a NestJS REST API

示例1:创建NestJS REST API

Input:
Create a TypeScript Lambda REST API using NestJS for a todo application
Process:
  1. Initialize NestJS project with
    nest new
  2. Install Lambda dependencies:
    @codegenie/serverless-express
    ,
    aws-lambda
  3. Create
    lambda.ts
    entry point with Express adapter
  4. Configure
    serverless.yml
    with API Gateway events
  5. Deploy with Serverless Framework
Output:
  • Complete NestJS project structure
  • REST API with CRUD endpoints
  • DynamoDB integration
  • Deployment configuration
输入:
为待办事项应用创建基于NestJS的TypeScript Lambda REST API
流程:
  1. 使用
    nest new
    初始化NestJS项目
  2. 安装Lambda依赖:
    @codegenie/serverless-express
    ,
    aws-lambda
  3. 创建带有Express适配器的
    lambda.ts
    入口文件
  4. 配置
    serverless.yml
    中的API Gateway事件
  5. 使用Serverless Framework部署
输出:
  • 完整的NestJS项目结构
  • 具备CRUD接口的REST API
  • DynamoDB集成
  • 部署配置

Example 2: Create a Raw TypeScript Lambda

示例2:创建原生TypeScript Lambda

Input:
Create a minimal TypeScript Lambda function with optimal cold start
Process:
  1. Set up TypeScript project with esbuild
  2. Create handler with proper AWS types
  3. Configure minimal dependencies
  4. Set up SAM or Serverless deployment
  5. Optimize bundle size with tree shaking
Output:
  • Minimal TypeScript Lambda project
  • Optimized bundle < 50KB
  • Cold start < 100ms
输入:
创建一个冷启动优化的轻量TypeScript Lambda函数
流程:
  1. 使用esbuild设置TypeScript项目
  2. 创建带有正确AWS类型的处理器
  3. 配置最小化依赖
  4. 设置SAM或Serverless部署
  5. 使用摇树优化减小包体积
输出:
  • 轻量TypeScript Lambda项目
  • 优化后的包体积<50KB
  • 冷启动时间<100毫秒

Example 3: Deploy with GitHub Actions

示例3:使用GitHub Actions部署

Input:
Configure CI/CD for TypeScript Lambda with SAM
Process:
  1. Create GitHub Actions workflow
  2. Set up Node.js environment
  3. Run tests with Jest
  4. Bundle with esbuild
  5. Deploy with SAM
Output:
  • Complete
    .github/workflows/deploy.yml
  • Multi-stage pipeline
  • Integrated test automation
输入:
为TypeScript Lambda配置基于SAM的CI/CD流水线
流程:
  1. 创建GitHub Actions工作流
  2. 设置Node.js环境
  3. 使用Jest运行测试
  4. 使用esbuild打包
  5. 使用SAM部署
输出:
  • 完整的
    .github/workflows/deploy.yml
  • 多阶段流水线
  • 集成测试自动化

Version

版本

Version: 1.0.0
版本:1.0.0