AWS Lambda TypeScript Integration Patterns for creating high-performance AWS Lambda functions in TypeScript with optimized cold starts. Overview Two approaches for TypeScript Lambda: 1. NestJS Framework - Dependency injection, modular architecture, larger bundle (100KB+) 2. Raw TypeScript - Minimal overhead, smaller bundle (<50KB), maximum control Both support API Gateway and ALB integration. When to Use - Creating new Lambda functions in TypeScript - Optimizing cold start performance - Choosing between NestJS and minimal TypeScript - Configuring API Gateway or ALB integration - Setting up CI…

: 'ts-jest',\n },\n collectCoverageFrom: [\n 'src/**/*.ts',\n '!src/**/*.d.ts',\n '!src/handlers/*.ts',\n ],\n coverageThreshold: {\n global: {\n branches: 80,\n functions: 80,\n lines: 80,\n statements: 80,\n },\n },\n moduleNameMapper: {\n '^@/(.*)

AWS Lambda TypeScript Integration Patterns for creating high-performance AWS Lambda functions in TypeScript with optimized cold starts. Overview Two approaches for TypeScript Lambda: 1. NestJS Framework - Dependency injection, modular architecture, larger bundle (100KB+) 2. Raw TypeScript - Minimal overhead, smaller bundle (<50KB), maximum control Both support API Gateway and ALB integration. When to Use - Creating new Lambda functions in TypeScript - Optimizing cold start performance - Choosing between NestJS and minimal TypeScript - Configuring API Gateway or ALB integration - Setting up CI…

: '\u003crootDir>/src/$1',\n },\n};\n```\n\n### Handler Unit Test\n\n```typescript\n// tests/handlers/api.handler.test.ts\nimport { APIGatewayProxyEvent, Context } from 'aws-lambda';\nimport { handler } from '../../src/handlers/api.handler';\n\nconst mockContext: Partial\u003cContext> = {\n awsRequestId: 'test-request-id',\n functionName: 'test-function',\n memoryLimitInMB: '256',\n invokedFunctionArn: 'arn:aws:lambda:us-east-1:123456789:function:test',\n getRemainingTimeInMillis: () => 30000,\n};\n\ndescribe('API Handler', () => {\n beforeEach(() => {\n jest.clearAllMocks();\n });\n\n it('should return 200 for health check', async () => {\n const event: Partial\u003cAPIGatewayProxyEvent> = {\n httpMethod: 'GET',\n path: '/health',\n headers: {},\n queryStringParameters: null,\n body: null,\n };\n\n const result = await handler(event as APIGatewayProxyEvent, mockContext as Context);\n\n expect(result.statusCode).toBe(200);\n const body = JSON.parse(result.body);\n expect(body.status).toBe('ok');\n });\n\n it('should return 404 for unknown routes', async () => {\n const event: Partial\u003cAPIGatewayProxyEvent> = {\n httpMethod: 'GET',\n path: '/unknown',\n headers: {},\n };\n\n const result = await handler(event as APIGatewayProxyEvent, mockContext as Context);\n\n expect(result.statusCode).toBe(404);\n });\n\n it('should return 400 for missing user ID', async () => {\n const event: Partial\u003cAPIGatewayProxyEvent> = {\n httpMethod: 'GET',\n path: '/users/{id}',\n pathParameters: {},\n headers: {},\n };\n\n const result = await handler(event as APIGatewayProxyEvent, mockContext as Context);\n\n expect(result.statusCode).toBe(400);\n });\n\n it('should return 400 for invalid JSON body', async () => {\n const event: Partial\u003cAPIGatewayProxyEvent> = {\n httpMethod: 'POST',\n path: '/users',\n body: 'invalid json',\n headers: {},\n };\n\n const result = await handler(event as APIGatewayProxyEvent, mockContext as Context);\n\n expect(result.statusCode).toBe(400);\n });\n});\n```\n\n### Service Test with Mocks\n\n```typescript\n// tests/services/user.service.test.ts\nimport { UserService } from '../../src/services/user.service';\nimport { IUserRepository } from '../../src/config/container';\n\nconst mockRepository: jest.Mocked\u003cIUserRepository> = {\n findById: jest.fn(),\n save: jest.fn(),\n delete: jest.fn(),\n};\n\ndescribe('UserService', () => {\n let service: UserService;\n\n beforeEach(() => {\n service = new UserService(mockRepository);\n jest.clearAllMocks();\n });\n\n describe('findById', () => {\n it('should return user when found', async () => {\n const user = { id: '123', name: 'John', email: '[email protected]' };\n mockRepository.findById.mockResolvedValue(user);\n\n const result = await service.findById('123');\n\n expect(result).toEqual(user);\n expect(mockRepository.findById).toHaveBeenCalledWith('123');\n });\n\n it('should return null when user not found', async () => {\n mockRepository.findById.mockResolvedValue(null);\n\n const result = await service.findById('999');\n\n expect(result).toBeNull();\n });\n });\n\n describe('create', () => {\n it('should create and return user', async () => {\n const input = { name: 'John', email: '[email protected]' };\n const created = { id: '123', ...input };\n mockRepository.save.mockResolvedValue(created);\n\n const result = await service.create(input);\n\n expect(result).toEqual(created);\n expect(mockRepository.save).toHaveBeenCalledWith(expect.objectContaining(input));\n });\n });\n});\n```\n\n---\n\n## Deployment\n\n### Serverless Framework\n\n```yaml\n# serverless.yml\nservice: raw-ts-lambda\n\nprovider:\n name: aws\n runtime: nodejs20.x\n stage: ${opt:stage, 'dev'}\n region: ${opt:region, 'us-east-1'}\n memorySize: 256\n timeout: 10\n environment:\n NODE_OPTIONS: '--enable-source-maps'\n STAGE: ${self:provider.stage}\n\n iam:\n role:\n statements:\n - Effect: Allow\n Action:\n - logs:CreateLogGroup\n - logs:CreateLogStream\n - logs:PutLogEvents\n Resource:\n - !Sub 'arn:aws:logs:${aws:region}:${aws:accountId}:log-group:/aws/lambda/${self:service}-*'\n - Effect: Allow\n Action:\n - dynamodb:GetItem\n - dynamodb:PutItem\n - dynamodb:UpdateItem\n - dynamodb:DeleteItem\n - dynamodb:Query\n - dynamodb:Scan\n Resource:\n - !GetAtt UsersTable.Arn\n\nplugins:\n - serverless-esbuild\n\ncustom:\n esbuild:\n bundle: true\n minify: ${self:custom.isProduction}\n sourcemap: true\n target: node20\n platform: node\n format: esm\n splitting: true\n entryPoints:\n - src/handlers/api.handler.ts\n - src/handlers/s3.handler.ts\n - src/handlers/sqs.handler.ts\n external:\n - aws-sdk\n\n isProduction: !Equals ['${self:provider.stage}', 'prod']\n\nfunctions:\n api:\n handler: dist/api.handler\n events:\n - http:\n path: /{proxy+}\n method: ANY\n cors: true\n\n s3Processor:\n handler: dist/s3.handler\n events:\n - s3:\n bucket: ${self:service}-input-${self:provider.stage}\n event: s3:ObjectCreated:*\n\n sqsProcessor:\n handler: dist/sqs.handler\n events:\n - sqs:\n arn:\n Fn::GetAtt:\n - ProcessingQueue\n - Arn\n batchSize: 10\n functionResponseType: ReportBatchItemFailures\n\nresources:\n Resources:\n UsersTable:\n Type: AWS::DynamoDB::Table\n Properties:\n TableName: ${self:service}-users-${self:provider.stage}\n BillingMode: PAY_PER_REQUEST\n AttributeDefinitions:\n - AttributeName: id\n AttributeType: S\n KeySchema:\n - AttributeName: id\n KeyType: HASH\n\n ProcessingQueue:\n Type: AWS::SQS::Queue\n Properties:\n QueueName: ${self:service}-processing-${self:provider.stage}\n VisibilityTimeout: 60\n```\n\n---\n\n## Best Practices Summary\n\n1. **Use static/module-level caching** for AWS clients and connections\n2. **Implement lazy loading** for expensive resources\n3. **Keep dependencies minimal** - only include what you need\n4. **Use esbuild** for fast bundling and smaller package size\n5. **Implement proper error handling** with structured responses\n6. **Use TypeScript strict mode** for better type safety\n7. **Write unit tests** with mocked dependencies\n8. **Use environment variables** for configuration\n9. **Enable source maps** for easier debugging\n10. **Monitor cold starts** and optimize initialization code\n\n## Cold Start Benchmarks\n\n| Configuration | Cold Start | Warm Start | Memory |\n|--------------|------------|------------|--------|\n| Minimal (no deps) | ~50ms | ~2ms | 128MB |\n| With DynamoDB client | ~150ms | ~5ms | 256MB |\n| With full AWS SDK | ~300ms | ~10ms | 512MB |\n\n## When to Use Raw TypeScript vs NestJS\n\n### Use Raw TypeScript when:\n- Maximum performance is critical\n- Minimal cold start is required\n- Simple handlers with minimal logic\n- Small team with no framework experience\n- Cost optimization is priority\n\n### Use NestJS when:\n- Complex application architecture\n- Team familiar with NestJS\n- Need dependency injection container\n- Multiple modules and services\n- Enterprise-grade requirements\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":27804,"content_sha256":"c2fffb807b478c607f57ef979b34f647d8244245115702e1db8c77d65de3aea9"},{"filename":"references/serverless-config.md","content":"# Serverless Configuration Reference\n\nComplete reference for deploying NestJS Lambda applications using Serverless Framework and AWS SAM.\n\n## Serverless Framework\n\n### Basic Configuration\n\n```yaml\nservice: nestjs-lambda-api\n\nprovider:\n name: aws\n runtime: nodejs20.x\n region: ${opt:region, 'us-east-1'}\n stage: ${opt:stage, 'dev'}\n memorySize: 512\n timeout: 29\n environment:\n NODE_ENV: production\n DATABASE_URL: ${ssm:/${self:service}/${self:provider.stage}/database-url}\n JWT_SECRET: ${ssm:/${self:service}/${self:provider.stage}/jwt-secret}\n iam:\n role:\n statements:\n - Effect: Allow\n Action:\n - logs:CreateLogGroup\n - logs:CreateLogStream\n - logs:PutLogEvents\n Resource:\n - !Sub 'arn:aws:logs:${aws:region}:${aws:accountId}:log-group:/aws/lambda/${self:service}-*'\n\npackage:\n individually: false\n patterns:\n - '!node_modules/**'\n - '!test/**'\n - '!.git/**'\n - 'dist/**'\n - '!dist/tsconfig.build.tsbuildinfo'\n\ncustom:\n esbuild:\n bundle: true\n minify: true\n target: node20\n platform: node\n external:\n - '@nestjs/microservices'\n - '@nestjs/websockets'\n - 'class-transformer/storage'\n\nfunctions:\n api:\n handler: dist/lambda.handler\n events:\n - http:\n path: /{proxy+}\n method: ANY\n cors: true\n - http:\n path: /\n method: ANY\n cors: true\n provisionedConcurrency: ${self:custom.provisionedConcurrency.${self:provider.stage}, 0}\n\ncustom:\n provisionedConcurrency:\n prod: 5\n dev: 0\n\nplugins:\n - serverless-esbuild\n - serverless-offline\n```\n\n### Commands\n\n```bash\n# Deploy\nserverless deploy\nserverless deploy --stage prod --region eu-west-1\n\n# Local development\nserverless offline\n\n# Logs\nserverless logs -f api -t\n\n# Remove\nserverless remove\n```\n\n## AWS SAM\n\n### Basic Template\n\n```yaml\nAWSTemplateFormatVersion: '2010-09-09'\nTransform: AWS::Serverless-2016-10-31\nDescription: NestJS Lambda API\n\nGlobals:\n Function:\n Timeout: 29\n MemorySize: 512\n Runtime: nodejs20.x\n Architectures:\n - x86_64\n\nParameters:\n Environment:\n Type: String\n Default: dev\n AllowedValues:\n - dev\n - staging\n - prod\n\nResources:\n NestJSApiFunction:\n Type: AWS::Serverless::Function\n Properties:\n FunctionName: !Sub '${AWS::StackName}-api'\n Handler: dist/lambda.handler\n CodeUri: ./\n Environment:\n Variables:\n NODE_ENV: !Ref Environment\n DATABASE_URL: !Sub '{{resolve:ssm-secure:/${AWS::StackName}/database-url}}'\n Events:\n ApiGatewayRoot:\n Type: Api\n Properties:\n Path: /\n Method: ANY\n RestApiId: !Ref ApiGatewayApi\n ApiGatewayProxy:\n Type: Api\n Properties:\n Path: /{proxy+}\n Method: ANY\n RestApiId: !Ref ApiGatewayApi\n Policies:\n - AWSLambdaBasicExecutionRole\n\n ApiGatewayApi:\n Type: AWS::Serverless::Api\n Properties:\n StageName: !Ref Environment\n Cors:\n AllowMethods: \"'GET,POST,PUT,DELETE,OPTIONS'\"\n AllowHeaders: \"'Content-Type,Authorization'\"\n AllowOrigin: !Sub \"'${AllowedOrigins}'\"\n\nOutputs:\n ApiUrl:\n Description: API Gateway endpoint URL\n Value: !Sub 'https://${ApiGatewayApi}.execute-api.${AWS::Region}.amazonaws.com/${Environment}/'\n```\n\n### Commands\n\n```bash\n# Build\nsam build\n\n# Local development\nsam local start-api --warm-containers EAGER\n\n# Deploy\nsam deploy --guided\nsam deploy --config-env prod\n\n# Logs\nsam logs -n NestJSApiFunction --tail\n\n# Delete\nsam delete\n```\n\n## Comparison\n\n| Feature | SAM | Serverless Framework |\n|---------|-----|---------------------|\n| Native AWS | Yes | No (uses CloudFormation) |\n| Local testing | `sam local` | `serverless-offline` |\n| CI/CD integration | AWS-native | Multi-cloud support |\n| Syntax | YAML/JSON | YAML/TypeScript/JavaScript |\n| Plugins | SAR, nested stacks | Rich plugin ecosystem |\n\n## When to Choose\n\n**Choose SAM when:**\n- Native AWS environment\n- Team familiar with CloudFormation\n- Deep AWS service integration needed\n- AWS CodePipeline/CodeBuild usage\n\n**Choose Serverless Framework when:**\n- Multi-cloud requirements\n- Large plugin ecosystem needed\n- Prefer TypeScript/JavaScript config\n- Easier local development preferred\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4360,"content_sha256":"abb2a10a242ff6ede6129f32479eaa084bbdb257f4e7045d20bf0fa4167d09bd"},{"filename":"references/serverless-deployment.md","content":"# Deployment Strategies for NestJS Lambda\n\n## Overview\n\nThis reference covers deployment strategies, CI/CD pipelines, and optimization techniques for NestJS Lambda applications using AWS SAM and Serverless Framework.\n\n## AWS SAM (Serverless Application Model)\n\n### Installation\n\n```bash\n# macOS\nbrew tap aws/tap\nbrew install aws-sam-cli\n\n# Linux\nwget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip\nunzip aws-sam-cli-linux-x86_64.zip -d sam-installation\nsudo ./sam-installation/install\n\n# Verify installation\nsam --version\n```\n\n### Project Structure\n\n```\nmy-nestjs-lambda/\n├── src/ # NestJS source code\n├── dist/ # Compiled output\n├── template.yaml # SAM template\n├── samconfig.toml # SAM configuration\n├── lambda.ts # Lambda entry point\n├── package.json\n└── tsconfig.json\n```\n\n### SAM Template Reference\n\n```yaml\nAWSTemplateFormatVersion: '2010-09-09'\nTransform: AWS::Serverless-2016-10-31\nDescription: NestJS Lambda Application\n\nGlobals:\n Function:\n Timeout: 29\n MemorySize: 512\n Runtime: nodejs20.x\n Architectures:\n - x86_64\n Environment:\n Variables:\n NODE_ENV: production\n LOG_LEVEL: info\n Tags:\n Application: NestJS API\n Environment: !Ref Environment\n\nParameters:\n Environment:\n Type: String\n Default: dev\n AllowedValues:\n - dev\n - staging\n - prod\n Description: Deployment environment\n\n DatabaseUrl:\n Type: String\n NoEcho: true\n Description: Database connection string\n\n AllowedOrigins:\n Type: String\n Default: \"\"\n Description: Comma-separated list of allowed CORS origins (leave empty to disable CORS)\n\nConditions:\n IsProduction: !Equals [!Ref Environment, prod]\n\nResources:\n # API Gateway\n ApiGatewayApi:\n Type: AWS::Serverless::Api\n Properties:\n StageName: !Ref Environment\n Cors:\n AllowMethods: \"'GET,POST,PUT,DELETE,OPTIONS'\"\n AllowHeaders: \"'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'\"\n AllowOrigin: !Sub \"'${AllowedOrigins}'\"\n MaxAge: \"'600'\"\n Auth:\n DefaultAuthorizer: CognitoAuthorizer\n Authorizers:\n CognitoAuthorizer:\n UserPoolArn: !GetAtt UserPool.Arn\n Identity:\n Header: Authorization\n ValidationExpression: ^Bearer [-0-9a-zA-Z\\._]*$\n\n # Lambda Function\n NestJSApiFunction:\n Type: AWS::Serverless::Function\n Properties:\n FunctionName: !Sub '${AWS::StackName}-api'\n Handler: dist/lambda.handler\n CodeUri: ./\n Description: NestJS API Lambda function\n Role: !GetAtt LambdaExecutionRole.Arn\n Environment:\n Variables:\n DATABASE_URL: !Ref DatabaseUrl\n JWT_SECRET: !Sub '{{resolve:secretsmanager:${JWTSecret}:SecretString:jwt}}'\n COGNITO_USER_POOL_ID: !Ref UserPool\n COGNITO_CLIENT_ID: !Ref UserPoolClient\n Events:\n ApiRoot:\n Type: Api\n Properties:\n RestApiId: !Ref ApiGatewayApi\n Path: /\n Method: ANY\n ApiProxy:\n Type: Api\n Properties:\n RestApiId: !Ref ApiGatewayApi\n Path: /{proxy+}\n Method: ANY\n ProvisionedConcurrencyConfig:\n ProvisionedConcurrentExecutions: !If [IsProduction, 5, 0]\n AutoPublishAlias: live\n DeploymentPreference:\n Type: Canary10Percent5Minutes\n Alarms:\n - !Ref ErrorAlarm\n - !Ref LatencyAlarm\n Hooks:\n PreTraffic: !Ref PreTrafficHookFunction\n PostTraffic: !Ref PostTrafficHookFunction\n\n # Lambda Execution Role\n LambdaExecutionRole:\n Type: AWS::IAM::Role\n Properties:\n AssumeRolePolicyDocument:\n Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Principal:\n Service: lambda.amazonaws.com\n Action: sts:AssumeRole\n ManagedPolicyArns:\n - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole\n Policies:\n - PolicyName: CloudWatchLogsPolicy\n PolicyDocument:\n Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Action:\n - logs:CreateLogGroup\n - logs:CreateLogStream\n - logs:PutLogEvents\n - logs:DescribeLogStreams\n Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*'\n\n - PolicyName: SecretsManagerPolicy\n PolicyDocument:\n Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Action:\n - secretsmanager:GetSecretValue\n Resource: !Ref JWTSecret\n\n - PolicyName: DynamoDBPolicy\n PolicyDocument:\n Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Action:\n - dynamodb:GetItem\n - dynamodb:PutItem\n - dynamodb:UpdateItem\n - dynamodb:DeleteItem\n - dynamodb:Query\n - dynamodb:Scan\n Resource: !GetAtt DynamoDBTable.Arn\n\n - PolicyName: S3Policy\n PolicyDocument:\n Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Action:\n - s3:GetObject\n - s3:PutObject\n - s3:DeleteObject\n Resource: !Sub '${S3Bucket.Arn}/*'\n\n # VPC Configuration for RDS access\n LambdaSecurityGroup:\n Type: AWS::EC2::SecurityGroup\n Properties:\n GroupDescription: Security group for Lambda functions\n VpcId: !Ref VPC\n SecurityGroupIngress: []\n SecurityGroupEgress:\n - IpProtocol: tcp\n FromPort: 443\n ToPort: 443\n CidrIp: 0.0.0.0/0\n - IpProtocol: tcp\n FromPort: 5432\n ToPort: 5432\n CidrIp: !Ref VPCCidr\n\n # DynamoDB Table\n DynamoDBTable:\n Type: AWS::DynamoDB::Table\n Properties:\n TableName: !Sub '${AWS::StackName}-data'\n BillingMode: PAY_PER_REQUEST\n AttributeDefinitions:\n - AttributeName: PK\n AttributeType: S\n - AttributeName: SK\n AttributeType: S\n - AttributeName: GSI1PK\n AttributeType: S\n - AttributeName: GSI1SK\n AttributeType: S\n KeySchema:\n - AttributeName: PK\n KeyType: HASH\n - AttributeName: SK\n KeyType: RANGE\n GlobalSecondaryIndexes:\n - IndexName: GSI1\n KeySchema:\n - AttributeName: GSI1PK\n KeyType: HASH\n - AttributeName: GSI1SK\n KeyType: RANGE\n Projection:\n ProjectionType: ALL\n StreamSpecification:\n StreamViewType: NEW_AND_OLD_IMAGES\n PointInTimeRecoverySpecification:\n PointInTimeRecoveryEnabled: !If [IsProduction, true, false]\n\n # S3 Bucket\n S3Bucket:\n Type: AWS::S3::Bucket\n Properties:\n BucketName: !Sub '${AWS::StackName}-assets-${AWS::AccountId}'\n PublicAccessBlockConfiguration:\n BlockPublicAcls: true\n BlockPublicPolicy: true\n IgnorePublicAcls: true\n RestrictPublicBuckets: true\n BucketEncryption:\n ServerSideEncryptionConfiguration:\n - ServerSideEncryptionByDefault:\n SSEAlgorithm: AES256\n LifecycleConfiguration:\n Rules:\n - Id: ExpireOldVersions\n Status: Enabled\n NoncurrentVersionExpirationInDays: 30\n\n # Secrets Manager\n JWTSecret:\n Type: AWS::SecretsManager::Secret\n Properties:\n Name: !Sub '${AWS::StackName}/jwt-secret'\n Description: JWT signing secret\n GenerateSecretString:\n SecretStringTemplate: '{\"jwt\":\"\"}'\n GenerateStringKey: jwt\n PasswordLength: 32\n ExcludeCharacters: '\"@/\\'\n\n # CloudWatch Alarms\n ErrorAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n AlarmName: !Sub '${AWS::StackName}-errors'\n AlarmDescription: Lambda error rate alarm\n MetricName: Errors\n Namespace: AWS/Lambda\n Statistic: Sum\n Period: 60\n EvaluationPeriods: 1\n Threshold: 1\n ComparisonOperator: GreaterThanOrEqualToThreshold\n Dimensions:\n - Name: FunctionName\n Value: !Ref NestJSApiFunction\n\n LatencyAlarm:\n Type: AWS::CloudWatch::Alarm\n Properties:\n AlarmName: !Sub '${AWS::StackName}-latency'\n AlarmDescription: Lambda duration alarm\n MetricName: Duration\n Namespace: AWS/Lambda\n Statistic: p99\n Period: 60\n EvaluationPeriods: 2\n Threshold: 5000\n ComparisonOperator: GreaterThanThreshold\n Dimensions:\n - Name: FunctionName\n Value: !Ref NestJSApiFunction\n\n # CloudWatch Log Group\n LambdaLogGroup:\n Type: AWS::Logs::LogGroup\n Properties:\n LogGroupName: !Sub '/aws/lambda/${NestJSApiFunction}'\n RetentionInDays: !If [IsProduction, 30, 7]\n\nOutputs:\n ApiUrl:\n Description: API Gateway endpoint URL\n Value: !Sub 'https://${ApiGatewayApi}.execute-api.${AWS::Region}.amazonaws.com/${Environment}/'\n Export:\n Name: !Sub '${AWS::StackName}-api-url'\n\n FunctionArn:\n Description: Lambda function ARN\n Value: !GetAtt NestJSApiFunction.Arn\n Export:\n Name: !Sub '${AWS::StackName}-function-arn'\n```\n\n### SAM Configuration (samconfig.toml)\n\n```toml\nversion = 0.1\n\n[default]\n[default.global.parameters]\nstack_name = \"nestjs-lambda-api\"\n\n[default.build.parameters]\ncached = true\nparallel = true\n\n[default.validate.parameters]\nlint = true\n\n[default.deploy.parameters]\ncapabilities = \"CAPABILITY_IAM CAPABILITY_AUTO_EXPAND\"\nconfirm_changeset = true\nresolve_s3 = true\ns3_prefix = \"nestjs-lambda-api\"\nregion = \"us-east-1\"\nimage_repositories = []\nparameter_overrides = [\n \"Environment=dev\"\n]\n\n[default.deploy.parameters.globals]\n[default.deploy.parameters.globals.parameters]\nparallel = true\n\n[dev.deploy.parameters]\nstack_name = \"nestjs-lambda-api-dev\"\nparameter_overrides = [\n \"Environment=dev\",\n \"DatabaseUrl=postgres://...\"\n]\n\n[staging.deploy.parameters]\nstack_name = \"nestjs-lambda-api-staging\"\nparameter_overrides = [\n \"Environment=staging\",\n \"DatabaseUrl=postgres://...\"\n]\n\n[prod.deploy.parameters]\nstack_name = \"nestjs-lambda-api-prod\"\nparameter_overrides = [\n \"Environment=prod\",\n \"DatabaseUrl=postgres://...\"\n]\n\n[default.sync.parameters]\nwatch = true\n\n[default.local_start_api.parameters]\nwarm_containers = \"EAGER\"\n\n[default.local_start_lambda.parameters]\nwarm_containers = \"EAGER\"\n```\n\n### SAM Commands\n\n```bash\n# Initialize SAM project\nsam init --runtime nodejs20.x --dependency-manager npm --app-template hello-world\n\n# Validate template\nsam validate --lint\n\n# Build application\nsam build\n\n# Local development\nsam local invoke NestJSApiFunction -e events/api-event.json\nsam local start-api --warm-containers EAGER\n\n# Deploy\nsam deploy --guided\nsam deploy --config-env prod\n\n# Sync (for development)\nsam sync --watch\n\n# Logs\nsam logs -n NestJSApiFunction --tail\n\n# Delete stack\nsam delete\n```\n\n### SAM Policy Templates\n\n```yaml\n# Inline policy for specific AWS services\nPolicies:\n - S3ReadPolicy:\n BucketName: !Ref S3Bucket\n - S3WritePolicy:\n BucketName: !Ref S3Bucket\n - DynamoDBReadPolicy:\n TableName: !Ref DynamoDBTable\n - DynamoDBCrudPolicy:\n TableName: !Ref DynamoDBTable\n - SESBulkTemplatedCrudPolicy:\n IdentityName: !Ref SESIdentity\n - SQSSendMessagePolicy:\n QueueName: !GetAtt SQSQueue.QueueName\n - SNSPublishMessagePolicy:\n TopicName: !GetAtt SNSTopic.TopicName\n - CloudWatchPutMetricPolicy: {}\n - VPCAccessPolicy: {}\n```\n\n## Serverless Framework\n\n### Installation\n\n```bash\n# Install Serverless Framework\nnpm install -g serverless\n\n# Or use npx\nnpx serverless\n\n# Verify installation\nserverless --version\n```\n\n### Project Structure\n\n```\nmy-nestjs-lambda/\n├── src/ # NestJS source code\n├── dist/ # Compiled output\n├── serverless.yml # Serverless configuration\n├── serverless.ts # TypeScript config (optional)\n├── lambda.ts # Lambda entry point\n├── package.json\n└── webpack.config.js\n```\n\n### Serverless Configuration Reference\n\n```yaml\nservice: nestjs-lambda-api\n\nframeworkVersion: '3'\n\nprovider:\n name: aws\n runtime: nodejs20.x\n stage: ${opt:stage, 'dev'}\n region: ${opt:region, 'us-east-1'}\n memorySize: 512\n timeout: 29\n logRetentionInDays: 14\n versionFunctions: true\n\n # Environment variables\n environment:\n NODE_ENV: production\n STAGE: ${self:provider.stage}\n SERVICE_NAME: ${self:service}\n DATABASE_URL: ${ssm:/${self:service}/${self:provider.stage}/database-url}\n JWT_SECRET: ${ssm:/${self:service}/${self:provider.stage}/jwt-secret~true}\n SENTRY_DSN: ${ssm:/${self:service}/${self:provider.stage}/sentry-dsn~true}\n\n # IAM role statements\n iam:\n role:\n name: ${self:service}-${self:provider.stage}-lambda-role\n statements:\n # CloudWatch Logs\n - Effect: Allow\n Action:\n - logs:CreateLogGroup\n - logs:CreateLogStream\n - logs:PutLogEvents\n Resource:\n - 'arn:aws:logs:${aws:region}:${aws:accountId}:log-group:/aws/lambda/*:*:*'\n\n # X-Ray Tracing\n - Effect: Allow\n Action:\n - xray:PutTraceSegments\n - xray:PutTelemetryRecords\n Resource:\n - !Sub 'arn:aws:xray:${aws:region}:${aws:accountId}:*'\n\n # SSM Parameter Store\n - Effect: Allow\n Action:\n - ssm:GetParameter\n - ssm:GetParameters\n Resource:\n - 'arn:aws:ssm:${aws:region}:${aws:accountId}:parameter/${self:service}/*'\n\n # DynamoDB\n - Effect: Allow\n Action:\n - dynamodb:GetItem\n - dynamodb:PutItem\n - dynamodb:UpdateItem\n - dynamodb:DeleteItem\n - dynamodb:Query\n - dynamodb:Scan\n - dynamodb:BatchGetItem\n - dynamodb:BatchWriteItem\n Resource:\n - !GetAtt DynamoDBTable.Arn\n - !Sub '${DynamoDBTable.Arn}/index/*'\n\n # S3\n - Effect: Allow\n Action:\n - s3:GetObject\n - s3:PutObject\n - s3:DeleteObject\n - s3:ListBucket\n Resource:\n - !GetAtt S3Bucket.Arn\n - !Sub '${S3Bucket.Arn}/*'\n\n # SQS\n - Effect: Allow\n Action:\n - sqs:SendMessage\n - sqs:SendMessageBatch\n - sqs:ReceiveMessage\n - sqs:DeleteMessage\n - sqs:GetQueueAttributes\n Resource:\n - !GetAtt SQSQueue.Arn\n\n # SNS\n - Effect: Allow\n Action:\n - sns:Publish\n Resource:\n - !Ref SNSTopic\n\n # SES\n - Effect: Allow\n Action:\n - ses:SendEmail\n - ses:SendRawEmail\n - ses:SendTemplatedEmail\n Resource:\n - !Sub 'arn:aws:ses:${aws:region}:${aws:accountId}:identity/${self:custom.email.from}'\n Condition:\n StringEquals:\n ses:FromAddress: ${self:custom.email.from}\n\n # Secrets Manager\n - Effect: Allow\n Action:\n - secretsmanager:GetSecretValue\n Resource:\n - 'arn:aws:secretsmanager:${aws:region}:${aws:accountId}:secret:${self:service}/*'\n\n # VPC configuration\n vpc:\n securityGroupIds:\n - !Ref LambdaSecurityGroup\n subnetIds:\n - !Ref PrivateSubnet1\n - !Ref PrivateSubnet2\n\n # API Gateway\n apiGateway:\n binaryMediaTypes:\n - '*/*'\n minimumCompressionSize: 1024\n\n # Tracing\n tracing:\n lambda: true\n apiGateway: true\n\n # Tags\n tags:\n Service: ${self:service}\n Stage: ${self:provider.stage}\n ManagedBy: serverless\n\n # Stack tags\n stackTags:\n Service: ${self:service}\n Stage: ${self:provider.stage}\n\nplugins:\n - serverless-esbuild\n - serverless-offline\n - serverless-plugin-aws-alerts\n - serverless-plugin-warmup\n\ncustom:\n # esbuild configuration\n esbuild:\n bundle: true\n minify: ${self:custom.isProduction}\n sourcemap: true\n target: node20\n platform: node\n format: cjs\n mainFields:\n - main\n - module\n external:\n - '@nestjs/microservices'\n - '@nestjs/websockets'\n - 'class-transformer/storage'\n - 'aws-sdk'\n keepNames: true\n splitting: false\n concurrency: 10\n packager: npm\n installExtraArgs: ['--legacy-peer-deps']\n\n # Offline configuration\n serverless-offline:\n httpPort: 3000\n host: 0.0.0.0\n lambdaPort: 3002\n noPrependStageInUrl: true\n\n # Warming configuration\n warmup:\n warmer:\n enabled: ${self:custom.isProduction}\n events:\n - schedule: rate(5 minutes)\n concurrency: 2\n\n # Alerts configuration\n alerts:\n stages:\n - prod\n dashboards: true\n topics:\n alarm:\n - !Ref AlarmTopic\n alarms:\n - functionErrors\n - functionThrottles\n - functionInvocations\n - functionDuration\n definitions:\n functionErrors:\n threshold: 1\n statistic: Sum\n period: 60\n evaluationPeriods: 1\n comparisonOperator: GreaterThanOrEqualToThreshold\n functionDuration:\n threshold: 5000\n statistic: p99\n period: 60\n evaluationPeriods: 2\n comparisonOperator: GreaterThanThreshold\n\n # Custom variables\n isProduction: !Equals ['${self:provider.stage}', 'prod']\n email:\n from: [email protected]\n\npackage:\n individually: false\n patterns:\n - '!**/*'\n - 'dist/**'\n - '!dist/**/*.map'\n - '!dist/**/*.spec.js'\n - '!dist/**/*.test.js'\n - '!dist/**/__tests__/**'\n - 'package.json'\n\nfunctions:\n api:\n name: ${self:service}-${self:provider.stage}-api\n handler: dist/lambda.handler\n description: NestJS API Lambda function\n memorySize: 512\n timeout: 29\n reservedConcurrency: 100\n provisionedConcurrency: ${self:custom.isProduction, 0}\n environment:\n FUNCTION_NAME: api\n events:\n - http:\n path: /{proxy+}\n method: ANY\n cors:\n origin: ${self:custom.cors.origins}\n headers:\n - Content-Type\n - Authorization\n - X-Amz-Date\n - X-Api-Key\n - X-Amz-Security-Token\n - X-Amz-User-Agent\n allowCredentials: true\n - http:\n path: /\n method: ANY\n cors: true\n iamRoleStatements:\n - Effect: Allow\n Action:\n - execute-api:Invoke\n Resource:\n - !Sub 'arn:aws:execute-api:${aws:region}:${aws:accountId}:${ApiGatewayRestApiId}/*'\n\n worker:\n name: ${self:service}-${self:provider.stage}-worker\n handler: dist/worker.handler\n description: Background worker Lambda\n memorySize: 256\n timeout: 900\n events:\n - sqs:\n arn:\n Fn::GetAtt:\n - SQSQueue\n - Arn\n batchSize: 10\n maximumBatchingWindowInSeconds: 5\n functionResponseType: ReportBatchItemFailures\n destinationConfig:\n onFailure:\n destination:\n Fn::GetAtt:\n - DLQ\n - Arn\n\n scheduler:\n name: ${self:service}-${self:provider.stage}-scheduler\n handler: dist/scheduler.handler\n description: Scheduled task Lambda\n memorySize: 256\n timeout: 300\n events:\n - schedule:\n rate: rate(1 hour)\n input:\n task: cleanup\n - schedule:\n rate: cron(0 2 * * ? *)\n input:\n task: daily-report\n\nresources:\n Resources:\n # DynamoDB Table\n DynamoDBTable:\n Type: AWS::DynamoDB::Table\n Properties:\n TableName: ${self:service}-${self:provider.stage}\n BillingMode: PAY_PER_REQUEST\n AttributeDefinitions:\n - AttributeName: PK\n AttributeType: S\n - AttributeName: SK\n AttributeType: S\n KeySchema:\n - AttributeName: PK\n KeyType: HASH\n - AttributeName: SK\n KeyType: RANGE\n PointInTimeRecoverySpecification:\n PointInTimeRecoveryEnabled: ${self:custom.isProduction}\n SSESpecification:\n SSEEnabled: true\n Tags:\n - Key: Service\n Value: ${self:service}\n - Key: Stage\n Value: ${self:provider.stage}\n\n # S3 Bucket\n S3Bucket:\n Type: AWS::S3::Bucket\n Properties:\n BucketName: ${self:service}-${self:provider.stage}-assets-${aws:accountId}\n PublicAccessBlockConfiguration:\n BlockPublicAcls: true\n BlockPublicPolicy: true\n IgnorePublicAcls: true\n RestrictPublicBuckets: true\n BucketEncryption:\n ServerSideEncryptionConfiguration:\n - ServerSideEncryptionByDefault:\n SSEAlgorithm: AES256\n LifecycleConfiguration:\n Rules:\n - Id: TransitionToIA\n Status: Enabled\n TransitionInDays: 30\n StorageClass: STANDARD_IA\n - Id: DeleteOldVersions\n Status: Enabled\n NoncurrentVersionExpirationInDays: 30\n\n # SQS Queue\n SQSQueue:\n Type: AWS::SQS::Queue\n Properties:\n QueueName: ${self:service}-${self:provider.stage}-queue\n VisibilityTimeout: 960\n MessageRetentionPeriod: 1209600\n RedrivePolicy:\n deadLetterTargetArn:\n Fn::GetAtt:\n - DLQ\n - Arn\n maxReceiveCount: 3\n\n # Dead Letter Queue\n DLQ:\n Type: AWS::SQS::Queue\n Properties:\n QueueName: ${self:service}-${self:provider.stage}-dlq\n MessageRetentionPeriod: 1209600\n\n # SNS Topic\n SNSTopic:\n Type: AWS::SNS::Topic\n Properties:\n TopicName: ${self:service}-${self:provider.stage}-topic\n\n # Alarm Topic\n AlarmTopic:\n Type: AWS::SNS::Topic\n Properties:\n TopicName: ${self:service}-${self:provider.stage}-alarms\n\n # Security Group\n LambdaSecurityGroup:\n Type: AWS::EC2::SecurityGroup\n Properties:\n GroupName: ${self:service}-${self:provider.stage}-lambda-sg\n GroupDescription: Security group for Lambda functions\n VpcId:\n Ref: VPC\n SecurityGroupEgress:\n - IpProtocol: tcp\n FromPort: 443\n ToPort: 443\n CidrIp: 0.0.0.0/0\n - IpProtocol: tcp\n FromPort: 5432\n ToPort: 5432\n CidrIp:\n Ref: VPCCidr\n\n Outputs:\n ApiGatewayRestApiId:\n Value:\n Ref: ApiGatewayRestApi\n Export:\n Name: ${self:service}-${self:provider.stage}-restApiId\n\n ApiGatewayRestApiRootResourceId:\n Value:\n Fn::GetAtt:\n - ApiGatewayRestApi\n - RootResourceId\n Export:\n Name: ${self:service}-${self:provider.stage}-rootResourceId\n```\n\n### Serverless TypeScript Configuration\n\n```typescript\n// serverless.ts\nimport type { AWS } from '@serverless/typescript';\n\nconst serverlessConfiguration: AWS = {\n service: 'nestjs-lambda-api',\n frameworkVersion: '3',\n plugins: [\n 'serverless-esbuild',\n 'serverless-offline',\n 'serverless-plugin-aws-alerts',\n ],\n provider: {\n name: 'aws',\n runtime: 'nodejs20.x',\n stage: '${opt:stage, \"dev\"}',\n region: '${opt:region, \"us-east-1\"}',\n memorySize: 512,\n timeout: 29,\n environment: {\n NODE_ENV: 'production',\n DATABASE_URL: '${ssm:/${self:service}/${self:provider.stage}/database-url}',\n },\n iam: {\n role: {\n statements: [\n {\n Effect: 'Allow',\n Action: ['logs:*'],\n Resource: {\n 'Fn::Sub': 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${self:service}-*',\n },\n },\n ],\n },\n },\n },\n functions: {\n api: {\n handler: 'dist/lambda.handler',\n events: [\n {\n http: {\n path: '/{proxy+}',\n method: 'ANY',\n cors: true,\n },\n },\n ],\n },\n },\n custom: {\n esbuild: {\n bundle: true,\n minify: true,\n target: 'node20',\n },\n },\n};\n\nmodule.exports = serverlessConfiguration;\n```\n\n### Serverless Commands\n\n```bash\n# Deploy\nserverless deploy\nserverless deploy --stage prod --region eu-west-1\nserverless deploy function -f api\n\n# Offline development\nserverless offline\nserverless offline start --reloadHandler\n\n# Logs\nserverless logs -f api -t\nserverless logs -f api --startTime 5m\n\n# Info\nserverless info\nserverless info --stage prod\n\n# Remove\nserverless remove\nserverless remove --stage dev\n\n# Print compiled config\nserverless print\n\n# Invoke function\nserverless invoke -f api -p event.json\nserverless invoke local -f api -p event.json\n\n# Metrics\nserverless metrics\nserverless metrics -f api --startTime 1h\n\n# Plugins\nserverless plugin install -n serverless-esbuild\nserverless plugin uninstall -n serverless-esbuild\nserverless plugin list\nserverless plugin search esbuild\n```\n\n## CI/CD Pipeline\n\n### GitHub Actions with SAM\n\n```yaml\n# .github/workflows/sam-deploy.yml\nname: SAM Deploy\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\nenv:\n AWS_REGION: us-east-1\n NODE_VERSION: '20'\n\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: ${{ env.NODE_VERSION }}\n cache: 'npm'\n\n - name: Install dependencies\n run: npm ci\n\n - name: Run tests\n run: npm test\n\n - name: Run lint\n run: npm run lint\n\n build:\n needs: test\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n\n - name: Setup SAM\n uses: aws-actions/setup-sam@v2\n\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: ${{ env.NODE_VERSION }}\n cache: 'npm'\n\n - name: Install dependencies\n run: npm ci\n\n - name: Build application\n run: npm run build\n\n - name: SAM Build\n run: sam build\n\n - name: Upload artifacts\n uses: actions/upload-artifact@v4\n with:\n name: sam-build\n path: |\n .aws-sam/\n dist/\n\n deploy-dev:\n needs: build\n runs-on: ubuntu-latest\n environment: development\n steps:\n - uses: actions/checkout@v4\n\n - name: Setup SAM\n uses: aws-actions/setup-sam@v2\n\n - name: Configure AWS credentials\n uses: aws-actions/configure-aws-credentials@v4\n with:\n aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}\n aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n aws-region: ${{ env.AWS_REGION }}\n\n - name: Download artifacts\n uses: actions/download-artifact@v4\n with:\n name: sam-build\n\n - name: SAM Deploy (Dev)\n run: |\n sam deploy --config-env dev \\\n --no-confirm-changeset \\\n --no-fail-on-empty-changeset\n\n deploy-prod:\n needs: deploy-dev\n runs-on: ubuntu-latest\n environment: production\n if: github.ref == 'refs/heads/main'\n steps:\n - uses: actions/checkout@v4\n\n - name: Setup SAM\n uses: aws-actions/setup-sam@v2\n\n - name: Configure AWS credentials\n uses: aws-actions/configure-aws-credentials@v4\n with:\n aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}\n aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n aws-region: ${{ env.AWS_REGION }}\n\n - name: Download artifacts\n uses: actions/download-artifact@v4\n with:\n name: sam-build\n\n - name: SAM Deploy (Prod)\n run: |\n sam deploy --config-env prod \\\n --no-confirm-changeset \\\n --no-fail-on-empty-changeset\n```\n\n### GitHub Actions with Serverless Framework\n\n```yaml\n# .github/workflows/serverless-deploy.yml\nname: Serverless Deploy\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\nenv:\n AWS_REGION: us-east-1\n NODE_VERSION: '20'\n\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: ${{ env.NODE_VERSION }}\n cache: 'npm'\n\n - name: Install dependencies\n run: npm ci\n\n - name: Run tests\n run: npm test\n\n - name: Run lint\n run: npm run lint\n\n deploy-dev:\n needs: test\n runs-on: ubuntu-latest\n environment: development\n steps:\n - uses: actions/checkout@v4\n\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: ${{ env.NODE_VERSION }}\n cache: 'npm'\n\n - name: Install Serverless\n run: npm install -g serverless\n\n - name: Configure AWS credentials\n uses: aws-actions/configure-aws-credentials@v4\n with:\n aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}\n aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n aws-region: ${{ env.AWS_REGION }}\n\n - name: Deploy to dev\n run: serverless deploy --stage dev\n\n deploy-prod:\n needs: deploy-dev\n runs-on: ubuntu-latest\n environment: production\n if: github.ref == 'refs/heads/main'\n steps:\n - uses: actions/checkout@v4\n\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: ${{ env.NODE_VERSION }}\n cache: 'npm'\n\n - name: Install Serverless\n run: npm install -g serverless\n\n - name: Configure AWS credentials\n uses: aws-actions/configure-aws-credentials@v4\n with:\n aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}\n aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n aws-region: ${{ env.AWS_REGION }}\n\n - name: Deploy to production\n run: serverless deploy --stage prod\n```\n\n## Build Optimization\n\n### Webpack Configuration\n\n```javascript\n// webpack.config.js\nconst path = require('path');\nconst nodeExternals = require('webpack-node-externals');\nconst TerserPlugin = require('terser-webpack-plugin');\nconst { IgnorePlugin } = require('webpack');\n\nmodule.exports = {\n entry: './lambda.ts',\n target: 'node',\n mode: 'production',\n externals: [nodeExternals()],\n module: {\n rules: [\n {\n test: /\\.ts$/,\n use: {\n loader: 'ts-loader',\n options: {\n transpileOnly: true,\n experimentalWatchApi: true,\n },\n },\n exclude: /node_modules/,\n },\n ],\n },\n resolve: {\n extensions: ['.ts', '.js'],\n alias: {\n '@': path.resolve(__dirname, 'src'),\n },\n },\n output: {\n filename: 'lambda.js',\n path: path.resolve(__dirname, 'dist'),\n libraryTarget: 'commonjs2',\n clean: true,\n },\n optimization: {\n minimizer: [\n new TerserPlugin({\n terserOptions: {\n keep_classnames: true,\n keep_fnames: true,\n compress: {\n drop_console: true,\n drop_debugger: true,\n },\n },\n }),\n ],\n },\n plugins: [\n // Ignore optional dependencies that aren't needed in Lambda\n new IgnorePlugin({\n resourceRegExp: /^@nestjs\\/microservices$/,\n }),\n new IgnorePlugin({\n resourceRegExp: /^@nestjs\\/websockets$/,\n }),\n ],\n stats: {\n modules: true,\n warnings: false,\n },\n};\n```\n\n### esbuild Configuration\n\n```javascript\n// esbuild.config.js\nconst esbuild = require('esbuild');\nconst { nodeExternalsPlugin } = require('esbuild-node-externals');\n\nasync function build() {\n try {\n await esbuild.build({\n entryPoints: ['lambda.ts', 'worker.ts', 'scheduler.ts'],\n bundle: true,\n platform: 'node',\n target: 'node20',\n outdir: 'dist',\n minify: process.env.NODE_ENV === 'production',\n sourcemap: true,\n splitting: false,\n format: 'cjs',\n metafile: true,\n external: [\n '@nestjs/microservices',\n '@nestjs/websockets',\n 'class-transformer/storage',\n 'aws-sdk', // Provided by Lambda runtime\n ],\n define: {\n 'process.env.NODE_ENV': '\"production\"',\n },\n plugins: [\n nodeExternalsPlugin({\n allowList: ['@nestjs/core', '@nestjs/common', '@nestjs/platform-express'],\n }),\n ],\n });\n\n console.log('Build completed successfully');\n } catch (error) {\n console.error('Build failed:', error);\n process.exit(1);\n }\n}\n\nbuild();\n```\n\n### esbuild with Serverless\n\n```yaml\n# serverless.yml with esbuild\ncustom:\n esbuild:\n bundle: true\n minify: ${self:custom.isProduction}\n sourcemap: true\n target: node20\n platform: node\n format: cjs\n mainFields:\n - main\n - module\n external:\n - '@nestjs/microservices'\n - '@nestjs/websockets'\n - 'class-transformer/storage'\n - 'aws-sdk'\n keepNames: true\n splitting: false\n concurrency: 10\n packager: npm\n installExtraArgs:\n - '--legacy-peer-deps'\n # Exclude specific paths from bundling\n exclude:\n - './test/**'\n - './**/*.spec.ts'\n - './**/*.test.ts'\n```\n\n## Package Optimization\n\n### Dependencies to Exclude\n\n```json\n{\n \"dependencies\": {\n \"@nestjs/common\": \"^10.0.0\",\n \"@nestjs/core\": \"^10.0.0\",\n \"@nestjs/platform-express\": \"^10.0.0\",\n \"@codegenie/serverless-express\": \"^4.0.0\",\n \"aws-lambda\": \"^1.0.0\",\n \"express\": \"^4.18.0\",\n \"reflect-metadata\": \"^0.1.13\",\n \"rxjs\": \"^7.8.0\"\n },\n \"devDependencies\": {\n \"@nestjs/testing\": \"^10.0.0\",\n \"@types/aws-lambda\": \"^8.10.0\",\n \"@types/express\": \"^4.17.0\",\n \"@types/node\": \"^20.0.0\",\n \"esbuild\": \"^0.20.0\",\n \"serverless\": \"^3.0.0\",\n \"serverless-esbuild\": \"^1.0.0\",\n \"serverless-offline\": \"^13.0.0\",\n \"ts-loader\": \"^9.0.0\",\n \"typescript\": \"^5.0.0\",\n \"webpack\": \"^5.0.0\",\n \"webpack-node-externals\": \"^3.0.0\"\n }\n}\n```\n\n### SAM Package Configuration\n\n```yaml\n# template.yaml - package optimization\nGlobals:\n Function:\n CodeUri: ./\n Runtime: nodejs20.x\n Architectures:\n - x86_64\n # Exclude dev dependencies\n Environment:\n Variables:\n NODE_ENV: production\n\nResources:\n NestJSApiFunction:\n Type: AWS::Serverless::Function\n Metadata:\n BuildMethod: esbuild\n BuildProperties:\n Minify: true\n Target: es2020\n Sourcemap: true\n EntryPoints:\n - lambda.ts\n External:\n - '@nestjs/microservices'\n - '@nestjs/websockets'\n Properties:\n Handler: dist/lambda.handler\n```\n\n## Environment Management\n\n### SAM Environment Variables\n\n```yaml\n# Using parameter overrides\nParameters:\n Environment:\n Type: String\n Default: dev\n\n # Secure parameters\n DatabaseUrl:\n Type: String\n NoEcho: true\n\nResources:\n MyFunction:\n Type: AWS::Serverless::Function\n Properties:\n Environment:\n Variables:\n STAGE: !Ref Environment\n DATABASE_URL: !Ref DatabaseUrl\n SECRET_VALUE: !Sub '{{resolve:secretsmanager:${MySecret}:SecretString:value}}'\n SSM_VALUE: !Sub '{{resolve:ssm-secure:/${Environment}/my-param}}'\n```\n\n### SSM Parameter Store\n\n```yaml\n# serverless.yml - SSM integration\nprovider:\n environment:\n # Standard parameters\n API_URL: ${ssm:/${self:service}/${self:provider.stage}/api-url}\n\n # Secure parameters (encrypted)\n DATABASE_URL: ${ssm:/${self:service}/${self:provider.stage}/database-url~true}\n\n # Reference by ARN\n EXTERNAL_API_KEY: ${ssm:arn:aws:ssm:${aws:region}:${aws:accountId}:parameter/external/api-key}\n\n iam:\n role:\n statements:\n - Effect: Allow\n Action:\n - ssm:GetParameter\n - ssm:GetParameters\n Resource:\n - arn:aws:ssm:${aws:region}:${aws:accountId}:parameter/${self:service}/*\n```\n\n### Secrets Manager\n\n```yaml\n# SAM with Secrets Manager\nResources:\n MySecret:\n Type: AWS::SecretsManager::Secret\n Properties:\n Name: !Sub '${AWS::StackName}/my-secret'\n GenerateSecretString:\n SecretStringTemplate: '{\"username\":\"admin\"}'\n GenerateStringKey: password\n PasswordLength: 32\n ExcludeCharacters: '\"@/\\'\n\n MyFunction:\n Type: AWS::Serverless::Function\n Properties:\n Environment:\n Variables:\n DB_SECRET: !Sub '{{resolve:secretsmanager:${MySecret}:SecretString}}'\n```\n\n```yaml\n# Serverless with Secrets Manager\nprovider:\n environment:\n # Full secret JSON\n DB_SECRET: ${secrets:${self:service}/${self:provider.stage}/database}\n\n # Specific key from secret\n DB_PASSWORD: ${secrets:${self:service}/${self:provider.stage}/database:password}\n\n iam:\n role:\n statements:\n - Effect: Allow\n Action:\n - secretsmanager:GetSecretValue\n Resource:\n - arn:aws:secretsmanager:${aws:region}:${aws:accountId}:secret:${self:service}/*\n```\n\n## Monitoring\n\n### SAM CloudWatch Dashboard\n\n```yaml\nResources:\n MonitoringDashboard:\n Type: AWS::CloudWatch::Dashboard\n Properties:\n DashboardName: !Sub '${AWS::StackName}-dashboard'\n DashboardBody: !Sub |\n {\n \"widgets\": [\n {\n \"type\": \"metric\",\n \"properties\": {\n \"title\": \"Invocations\",\n \"metrics\": [\n [\"AWS/Lambda\", \"Invocations\", \"FunctionName\", \"${NestJSApiFunction}\", { \"stat\": \"Sum\" }]\n ],\n \"period\": 300,\n \"region\": \"${AWS::Region}\",\n \"yAxis\": { \"left\": { \"min\": 0 } }\n }\n },\n {\n \"type\": \"metric\",\n \"properties\": {\n \"title\": \"Errors\",\n \"metrics\": [\n [\"AWS/Lambda\", \"Errors\", \"FunctionName\", \"${NestJSApiFunction}\", { \"stat\": \"Sum\" }],\n [\".\", \"Throttles\", \".\", \".\", { \"stat\": \"Sum\" }]\n ],\n \"period\": 300,\n \"region\": \"${AWS::Region}\"\n }\n },\n {\n \"type\": \"metric\",\n \"properties\": {\n \"title\": \"Duration\",\n \"metrics\": [\n [\"AWS/Lambda\", \"Duration\", \"FunctionName\", \"${NestJSApiFunction}\", { \"stat\": \"p99\" }],\n [\"...\", { \"stat\": \"Average\" }]\n ],\n \"period\": 300,\n \"region\": \"${AWS::Region}\"\n }\n }\n ]\n }\n```\n\n### Serverless CloudWatch Alarms\n\n```yaml\ncustom:\n alerts:\n stages:\n - prod\n - staging\n dashboards: true\n topics:\n alarm:\n - !Ref AlarmTopic\n ok:\n - !Ref OkTopic\n\n alarms:\n - functionErrors\n - functionThrottles\n - functionInvocations\n - functionDuration\n\n definitions:\n functionErrors:\n description: 'Function errors exceeded threshold'\n threshold: 1\n statistic: Sum\n period: 60\n evaluationPeriods: 1\n comparisonOperator: GreaterThanOrEqualToThreshold\n treatMissingData: notBreaching\n\n functionThrottles:\n description: 'Function throttled'\n threshold: 1\n statistic: Sum\n period: 60\n evaluationPeriods: 1\n comparisonOperator: GreaterThanOrEqualToThreshold\n\n functionDuration:\n description: 'Function duration exceeded threshold'\n threshold: 5000\n statistic: p99\n period: 60\n evaluationPeriods: 2\n comparisonOperator: GreaterThanThreshold\n\n customAlarm:\n description: 'Custom business metric'\n metric: CustomMetric\n namespace: MyNamespace\n threshold: 100\n statistic: Average\n period: 300\n evaluationPeriods: 1\n```\n\n### X-Ray Tracing\n\n```yaml\n# SAM - Enable tracing\nGlobals:\n Function:\n Tracing: Active\n\nResources:\n ApiGatewayApi:\n Type: AWS::Serverless::Api\n Properties:\n TracingEnabled: true\n```\n\n```yaml\n# Serverless - Enable tracing\nprovider:\n tracing:\n lambda: true\n apiGateway: true\n```\n\n```typescript\n// X-Ray instrumentation\nimport * as AWSXRay from 'aws-xray-sdk-core';\nimport * as AWS from 'aws-sdk';\n\n// Capture AWS SDK calls\nconst tracedAWS = AWSXRay.captureAWS(AWS);\n\n// Capture HTTP requests\nimport http from 'http';\nimport https from 'https';\nAWSXRay.captureHTTPsGlobal(http);\nAWSXRay.captureHTTPsGlobal(https);\n\n// Custom subsegment\nconst segment = AWSXRay.getSegment();\nconst subsegment = segment?.addNewSubsegment('custom-operation');\ntry {\n // Your code\n subsegment?.close();\n} catch (error) {\n subsegment?.close(error);\n}\n```\n\n## Performance Tuning\n\n### Memory Configuration\n\n```yaml\n# SAM - Memory and CPU tuning\nResources:\n ApiFunction:\n Type: AWS::Serverless::Function\n Properties:\n MemorySize: 512\n # Memory impacts CPU proportionally\n # 1769MB = 1 vCPU\n # 3008MB = ~1.7 vCPU\n\n ComputeIntensiveFunction:\n Type: AWS::Serverless::Function\n Properties:\n MemorySize: 3008\n```\n\n```yaml\n# Serverless - Memory per function\nfunctions:\n api:\n memorySize: 512\n\n compute:\n memorySize: 1024\n\n health:\n memorySize: 256\n```\n\n### Provisioned Concurrency\n\n```yaml\n# SAM - Provisioned Concurrency\nResources:\n MyFunction:\n Type: AWS::Serverless::Function\n Properties:\n ProvisionedConcurrencyConfig:\n ProvisionedConcurrentExecutions: 10\n AutoPublishAlias: live\n```\n\n```yaml\n# Serverless - Provisioned Concurrency\nfunctions:\n api:\n provisionedConcurrency: 10\n```\n\n### Reserved Concurrency\n\n```yaml\n# SAM - Reserved Concurrency\nResources:\n MyFunction:\n Type: AWS::Serverless::Function\n Properties:\n ReservedConcurrentExecutions: 100\n```\n\n```yaml\n# Serverless - Reserved Concurrency\nfunctions:\n api:\n reservedConcurrency: 100\n```\n\n## Rollback Strategy\n\n### SAM Auto-Rollback\n\n```yaml\nResources:\n MyFunction:\n Type: AWS::Serverless::Function\n Properties:\n AutoPublishAlias: live\n DeploymentPreference:\n Type: Canary10Percent5Minutes\n Alarms:\n - !Ref ErrorAlarm\n - !Ref LatencyAlarm\n Hooks:\n PreTraffic: !Ref PreTrafficHook\n PostTraffic: !Ref PostTrafficHook\n\n PreTrafficHook:\n Type: AWS::Serverless::Function\n Properties:\n Handler: hooks.preTraffic\n Runtime: nodejs20.x\n Policies:\n - Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Action:\n - codedeploy:PutLifecycleEventHookExecutionStatus\n Resource:\n - !Sub 'arn:aws:codedeploy:${aws:region}:${aws:accountId}:deploymentgroup:${AWS::StackName}/*'\n\n PostTrafficHook:\n Type: AWS::Serverless::Function\n Properties:\n Handler: hooks.postTraffic\n Runtime: nodejs20.x\n Policies:\n - Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Action:\n - codedeploy:PutLifecycleEventHookExecutionStatus\n Resource:\n - !Sub 'arn:aws:codedeploy:${aws:region}:${aws:accountId}:deploymentgroup:${AWS::StackName}/*'\n```\n\n### Serverless Canary\n\n```yaml\ncustom:\n canary:\n type: LinearCanary\n alias: Live\n linearTrafficShifting:\n - intervalMinutes: 10\n percentage: 10\n - intervalMinutes: 10\n percentage: 50\n - intervalMinutes: 10\n percentage: 100\n alarms:\n - functionErrors\n - functionDuration\n```\n\n## Security Best Practices\n\n### SAM VPC Configuration\n\n```yaml\nResources:\n MyFunction:\n Type: AWS::Serverless::Function\n Properties:\n VpcConfig:\n SecurityGroupIds:\n - !Ref LambdaSecurityGroup\n SubnetIds:\n - !Ref PrivateSubnet1\n - !Ref PrivateSubnet2\n Policies:\n - VPCAccessPolicy: {}\n```\n\n### Serverless VPC\n\n```yaml\nprovider:\n vpc:\n securityGroupIds:\n - !Ref LambdaSecurityGroup\n subnetIds:\n - !Ref PrivateSubnet1\n - !Ref PrivateSubnet2\n```\n\n### IAM Least Privilege\n\n```yaml\n# SAM - Granular IAM\nResources:\n MyFunction:\n Type: AWS::Serverless::Function\n Properties:\n Policies:\n - Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Action:\n - dynamodb:GetItem\n - dynamodb:PutItem\n Resource:\n - !GetAtt MyTable.Arn\n Condition:\n ForAllValues:StringEquals:\n dynamodb:LeadingKeys:\n - 'USER#${cognito-identity.amazonaws.com:sub}'\n```\n\n```yaml\n# Serverless - Granular IAM\nprovider:\n iam:\n role:\n statements:\n - Effect: Allow\n Action:\n - dynamodb:GetItem\n - dynamodb:PutItem\n Resource:\n - !GetAtt MyTable.Arn\n Condition:\n ForAllValues:StringEquals:\n dynamodb:LeadingKeys:\n - 'USER#${cognito-identity.amazonaws.com:sub}'\n```\n\n## Cost Optimization\n\n### Graviton2 (ARM64)\n\n```yaml\n# SAM - ARM64\nGlobals:\n Function:\n Architectures:\n - arm64\n```\n\n```yaml\n# Serverless - ARM64\nprovider:\n architecture: arm64\n```\n\n### SAM Lambda Layers\n\n```yaml\nResources:\n CommonLayer:\n Type: AWS::Serverless::LayerVersion\n Properties:\n LayerName: common-dependencies\n ContentUri: layers/common/\n CompatibleRuntimes:\n - nodejs20.x\n RetentionPolicy: Retain\n\n MyFunction:\n Type: AWS::Serverless::Function\n Properties:\n Layers:\n - !Ref CommonLayer\n```\n\n### Serverless Lambda Layers\n\n```yaml\nlayers:\n common:\n path: layers/common\n compatibleRuntimes:\n - nodejs20.x\n package:\n patterns:\n - 'node_modules/**'\n\nfunctions:\n api:\n layers:\n - { Ref: CommonLambdaLayer }\n```\n\n## SAM vs Serverless Framework\n\n| Feature | SAM | Serverless Framework |\n|---------|-----|---------------------|\n| Native AWS | Yes | No (uses CloudFormation) |\n| Local testing | `sam local` | `serverless-offline` |\n| CI/CD integration | AWS-native | Multi-cloud support |\n| Syntax | YAML/JSON | YAML/TypeScript/JavaScript |\n| Extensions | SAR, nested stacks | Plugins ecosystem |\n| Debugging | SAM CLI | Serverless console |\n\n### When to Choose SAM\n\n- Native AWS environment\n- Team familiar with CloudFormation\n- Need deep AWS service integration\n- Want to use AWS CodePipeline/CodeBuild\n\n### When to Choose Serverless Framework\n\n- Multi-cloud requirements\n- Large plugin ecosystem needed\n- Prefer TypeScript/JavaScript config\n- Want easier local development\n\n## Complete Example Project\n\n```\nnestjs-lambda-sam/\n├── src/\n│ ├── app.module.ts\n│ ├── main.ts\n│ ├── lambda.ts\n│ └── modules/\n│ └── users/\n├── dist/\n├── template.yaml\n├── samconfig.toml\n├── package.json\n└── tsconfig.json\n```\n\n```\nnestjs-lambda-serverless/\n├── src/\n│ ├── app.module.ts\n│ ├── main.ts\n│ ├── lambda.ts\n│ └── modules/\n│ └── users/\n├── dist/\n├── serverless.yml\n├── package.json\n└── tsconfig.json\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":47505,"content_sha256":"5ae8bdfe2612dd052c12e5ed4408cc17653f8c42be3767f8de086726ca5dcee5"},{"filename":"references/testing.md","content":"# Testing Lambda Functions\n\nComplete guide for testing NestJS Lambda handlers including unit tests, integration tests, and mocking strategies.\n\n## Unit Tests for Handler\n\nTest the Lambda handler in isolation with mocked AWS Lambda context.\n\n```typescript\n// lambda.spec.ts\nimport { handler } from './lambda';\nimport { Context } from 'aws-lambda';\n\ndescribe('Lambda Handler', () => {\n const mockContext: Partial\u003cContext> = {\n functionName: 'test-function',\n memoryLimitInMB: '512',\n invokedFunctionArn: 'arn:aws:lambda:us-east-1:123456789:function:test',\n awsRequestId: 'test-request-id',\n };\n\n beforeEach(() => {\n // Reset cached server for cold start tests\n jest.resetModules();\n });\n\n it('should bootstrap on first invocation (cold start)', async () => {\n const event = {\n httpMethod: 'GET',\n path: '/api/health',\n headers: {},\n body: null,\n };\n\n const result = await handler(event, mockContext as Context, () => {});\n\n expect(result.statusCode).toBe(200);\n });\n\n it('should reuse instance on warm invocation', async () => {\n const event = {\n httpMethod: 'GET',\n path: '/api/health',\n headers: {},\n body: null,\n };\n\n // First invocation\n await handler(event, mockContext as Context, () => {});\n\n // Second invocation (should use cached server)\n const start = Date.now();\n const result = await handler(event, mockContext as Context, () => {});\n const duration = Date.now() - start;\n\n expect(result.statusCode).toBe(200);\n expect(duration).toBeLessThan(100); // Warm start should be fast\n });\n});\n```\n\n## Integration Test with serverless-offline\n\nTest the full request/response cycle using the serverless-offline plugin.\n\n```typescript\n// test/lambda.integration.spec.ts\ndescribe('Lambda Integration', () => {\n let server: any;\n\n beforeAll(async () => {\n // Bootstrap for local testing\n const { bootstrap } = await import('../lambda');\n server = await bootstrap();\n });\n\n afterAll(async () => {\n if (server) {\n // Cleanup\n }\n });\n\n it('should handle API Gateway events', async () => {\n const event = {\n httpMethod: 'POST',\n path: '/api/users',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name: 'Test User' }),\n };\n\n const result = await server(event, {});\n\n expect(result.statusCode).toBe(201);\n expect(JSON.parse(result.body)).toHaveProperty('id');\n });\n});\n```\n\n## Mocking Strategies\n\n### Mock AWS Services\n\n```typescript\n// __mocks__/aws-sdk.ts\nexport const mockSend = jest.fn();\n\nexport const DynamoDBClient = jest.fn(() => ({\n send: mockSend,\n}));\n\nexport const GetItemCommand = jest.fn();\nexport const PutItemCommand = jest.fn();\n```\n\n### Mock NestJS Services\n\n```typescript\n// test/mocks/services.mock.ts\nexport const createMockUserService = () => ({\n findById: jest.fn(),\n create: jest.fn(),\n update: jest.fn(),\n delete: jest.fn(),\n});\n\n// In test\nconst mockUserService = createMockUserService();\nmockUserService.findById.mockResolvedValue({ id: '123', name: 'Test' });\n```\n\n### Mock Lambda Context\n\n```typescript\n// test/utils/lambda-context.ts\nimport { Context } from 'aws-lambda';\n\nexport function createMockContext(overrides?: Partial\u003cContext>): Context {\n return {\n awsRequestId: 'test-request-id',\n functionName: 'test-function',\n memoryLimitInMB: '512',\n invokedFunctionArn: 'arn:aws:lambda:us-east-1:123456789:function:test',\n getRemainingTimeInMillis: () => 30000,\n done: () => {},\n fail: () => {},\n succeed: () => {},\n ...overrides,\n } as Context;\n}\n```\n\n## Best Practices for Testing\n\n1. **Reset module cache** between tests to test cold/warm start behavior\n2. **Mock external services** (DynamoDB, S3, etc.) to avoid real AWS calls\n3. **Test both cold and warm starts** to verify caching works correctly\n4. **Use realistic event payloads** matching API Gateway format\n5. **Measure timing** for warm invocations to detect performance regressions\n6. **Test error scenarios** including timeouts and service failures\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4067,"content_sha256":"7e93cab47d4efecf2ffc1b3b68ac11d6b6d7f705b961acc3145a37ca09a42c79"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"AWS Lambda TypeScript Integration","type":"text"}]},{"type":"paragraph","content":[{"text":"Patterns for creating high-performance AWS Lambda functions in TypeScript with optimized cold starts.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"Two approaches for TypeScript Lambda:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NestJS Framework","type":"text","marks":[{"type":"strong"}]},{"text":" - Dependency injection, modular architecture, larger bundle (100KB+)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Raw TypeScript","type":"text","marks":[{"type":"strong"}]},{"text":" - Minimal overhead, smaller bundle (\u003c50KB), maximum control","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Both support API Gateway and ALB integration.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Creating new Lambda functions in TypeScript","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Optimizing cold start performance","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Choosing between NestJS and minimal TypeScript","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configuring API Gateway or ALB integration","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Setting up CI/CD for TypeScript Lambda","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Instructions","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"1. Choose Your Approach","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Approach","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cold Start","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Bundle Size","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Best For","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Complexity","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NestJS","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003c 500ms","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Larger (100KB+)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Complex APIs, enterprise apps, DI needed","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Medium","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Raw TypeScript","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003c 100ms","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Smaller (\u003c 50KB)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Simple handlers, microservices, minimal deps","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Low","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"2. Project Structure","type":"text"}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"NestJS Structure","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"my-nestjs-lambda/\n├── src/\n│ ├── app.module.ts\n│ ├── main.ts\n│ ├── lambda.ts # Lambda entry point\n│ └── modules/\n│ └── api/\n├── package.json\n├── tsconfig.json\n└── serverless.yml","type":"text"}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"Raw TypeScript Structure","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"my-ts-lambda/\n├── src/\n│ ├── handlers/\n│ │ └── api.handler.ts\n│ ├── services/\n│ └── utils/\n├── dist/ # Compiled output\n├── package.json\n├── tsconfig.json\n└── template.yaml","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"3. Implementation Examples","type":"text"}]},{"type":"paragraph","content":[{"text":"See the ","type":"text"},{"text":"References","type":"text","marks":[{"type":"link","attrs":{"href":"#references","title":null}}]},{"text":" section for detailed implementation guides. Quick examples:","type":"text"}]},{"type":"paragraph","content":[{"text":"NestJS Handler:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// lambda.ts\nimport { NestFactory } from '@nestjs/core';\nimport { ExpressAdapter } from '@nestjs/platform-express';\nimport serverlessExpress from '@codegenie/serverless-express';\nimport { Context, Handler } from 'aws-lambda';\nimport express from 'express';\nimport { AppModule } from './src/app.module';\n\nlet cachedServer: Handler;\n\nasync function bootstrap(): Promise\u003cHandler> {\n const expressApp = express();\n const adapter = new ExpressAdapter(expressApp);\n const nestApp = await NestFactory.create(AppModule, adapter);\n await nestApp.init();\n return serverlessExpress({ app: expressApp });\n}\n\nexport const handler: Handler = async (event: any, context: Context) => {\n if (!cachedServer) {\n cachedServer = await bootstrap();\n }\n return cachedServer(event, context);\n};","type":"text"}]},{"type":"paragraph","content":[{"text":"Raw TypeScript Handler:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// src/handlers/api.handler.ts\nimport { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';\n\nexport const handler = async (\n event: APIGatewayProxyEvent,\n context: Context\n): Promise\u003cAPIGatewayProxyResult> => {\n return {\n statusCode: 200,\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: 'Hello from TypeScript Lambda!' })\n };\n};","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core Concepts","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Cold Start Optimization","type":"text"}]},{"type":"paragraph","content":[{"text":"TypeScript cold start depends on bundle size and initialization code. Key strategies:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Lazy Loading","type":"text","marks":[{"type":"strong"}]},{"text":" - Defer heavy imports until needed","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tree Shaking","type":"text","marks":[{"type":"strong"}]},{"text":" - Remove unused code from bundle","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Minification","type":"text","marks":[{"type":"strong"}]},{"text":" - Use esbuild or terser for smaller bundles","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Instance Caching","type":"text","marks":[{"type":"strong"}]},{"text":" - Cache initialized services between invocations","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"Raw TypeScript Lambda","type":"text","marks":[{"type":"link","attrs":{"href":"references/raw-typescript-lambda.md#cold-start-optimization","title":null}}]},{"text":" for detailed patterns.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Connection Management","type":"text"}]},{"type":"paragraph","content":[{"text":"Create clients at module level and reuse:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// GOOD: Initialize once, reuse across invocations\nimport { DynamoDBClient } from '@aws-sdk/client-dynamodb';\n\nconst dynamoClient = new DynamoDBClient({ region: process.env.AWS_REGION });\n\nexport const handler = async (event: APIGatewayProxyEvent) => {\n // Use dynamoClient - already initialized\n};","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Environment Configuration","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// src/config/env.config.ts\nexport const env = {\n region: process.env.AWS_REGION || 'us-east-1',\n tableName: process.env.TABLE_NAME || '',\n debug: process.env.DEBUG === 'true',\n};\n\n// Validate required variables\nif (!env.tableName) {\n throw new Error('TABLE_NAME environment variable is required');\n}","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Best Practices","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Memory and Timeout Configuration","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Memory","type":"text","marks":[{"type":"strong"}]},{"text":": Start with 512MB for NestJS, 256MB for raw TypeScript","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Timeout","type":"text","marks":[{"type":"strong"}]},{"text":": Set based on cold start + expected processing time","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NestJS: 10-30 seconds for cold start buffer","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Raw TypeScript: 3-10 seconds typically sufficient","type":"text"}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Dependencies","type":"text"}]},{"type":"paragraph","content":[{"text":"Keep ","type":"text"},{"text":"package.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" minimal:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{\n \"dependencies\": {\n \"aws-lambda\": \"^3.1.0\",\n \"@aws-sdk/client-dynamodb\": \"^3.450.0\"\n },\n \"devDependencies\": {\n \"typescript\": \"^5.3.0\",\n \"esbuild\": \"^0.19.0\"\n }\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Error Handling","type":"text"}]},{"type":"paragraph","content":[{"text":"Return proper HTTP codes with structured errors:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"export const handler = async (event: APIGatewayProxyEvent): Promise\u003cAPIGatewayProxyResult> => {\n try {\n const result = await processEvent(event);\n return {\n statusCode: 200,\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(result)\n };\n } catch (error) {\n console.error('Error processing request:', error);\n return {\n statusCode: 500,\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ error: 'Internal server error' })\n };\n }\n};","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Logging","type":"text"}]},{"type":"paragraph","content":[{"text":"Use structured logging for CloudWatch Insights:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"const log = (level: string, message: string, meta?: object) => {\n console.log(JSON.stringify({\n level,\n message,\n timestamp: new Date().toISOString(),\n ...meta\n }));\n};\n\nlog('info', 'Request processed', { requestId: context.awsRequestId });","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Deployment Options","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Quick Start","type":"text"}]},{"type":"paragraph","content":[{"text":"Serverless Framework:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"yaml"},"content":[{"text":"service: my-typescript-api\n\nprovider:\n name: aws\n runtime: nodejs20.x\n\nfunctions:\n api:\n handler: dist/handler.handler\n events:\n - http:\n path: /{proxy+}\n method: ANY","type":"text"}]},{"type":"paragraph","content":[{"text":"AWS SAM:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"yaml"},"content":[{"text":"AWSTemplateFormatVersion: '2010-09-09'\nTransform: AWS::Serverless-2016-10-31\n\nResources:\n ApiFunction:\n Type: AWS::Serverless::Function\n Properties:\n CodeUri: dist/\n Handler: handler.handler\n Runtime: nodejs20.x\n Events:\n ApiEvent:\n Type: Api\n Properties:\n Path: /{proxy+}\n Method: ANY","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Deployment Validation","type":"text"}]},{"type":"paragraph","content":[{"text":"Pre-deploy checks:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run ","type":"text"},{"text":"npm test","type":"text","marks":[{"type":"code_inline"}]},{"text":" - verify all tests pass","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run ","type":"text"},{"text":"npm run build","type":"text","marks":[{"type":"code_inline"}]},{"text":" - confirm TypeScript compiles without errors","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verify bundle size \u003c 50MB (unzipped)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run ","type":"text"},{"text":"serverless invoke local","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"sam local invoke","type":"text","marks":[{"type":"code_inline"}]},{"text":" - test locally","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Post-deploy verification:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run ","type":"text"},{"text":"serverless invoke","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"aws lambda invoke","type":"text","marks":[{"type":"code_inline"}]},{"text":" - verify handler executes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test API endpoint via curl or Postman","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check CloudWatch logs for errors","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verify cold start time meets SLA","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"For complete deployment configurations including CI/CD, see ","type":"text"},{"text":"Serverless Deployment","type":"text","marks":[{"type":"link","attrs":{"href":"references/serverless-deployment.md","title":null}}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Constraints and Warnings","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Lambda Limits","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Deployment package","type":"text","marks":[{"type":"strong"}]},{"text":": 250MB unzipped maximum (50MB zipped)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Memory","type":"text","marks":[{"type":"strong"}]},{"text":": 128MB to 10GB","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Timeout","type":"text","marks":[{"type":"strong"}]},{"text":": 15 minutes maximum","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Concurrent executions","type":"text","marks":[{"type":"strong"}]},{"text":": 1000 default (adjustable)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Environment variables","type":"text","marks":[{"type":"strong"}]},{"text":": 4KB total size","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"TypeScript-Specific Considerations","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Bundle size","type":"text","marks":[{"type":"strong"}]},{"text":": TypeScript compiles to JavaScript; use bundlers to minimize size","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Cold start","type":"text","marks":[{"type":"strong"}]},{"text":": Node.js 20.x offers best performance","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dependencies","type":"text","marks":[{"type":"strong"}]},{"text":": Use Lambda Layers for shared dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Native modules","type":"text","marks":[{"type":"strong"}]},{"text":": Must be compiled for Amazon Linux 2","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Common Pitfalls","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Importing heavy libraries at module level","type":"text","marks":[{"type":"strong"}]},{"text":" - Defer to lazy loading if not always needed","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Not bundling dependencies","type":"text","marks":[{"type":"strong"}]},{"text":" - Include all production dependencies in the package","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Missing type definitions","type":"text","marks":[{"type":"strong"}]},{"text":" - Install ","type":"text"},{"text":"@types/aws-lambda","type":"text","marks":[{"type":"code_inline"}]},{"text":" for proper event typing","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No timeout handling","type":"text","marks":[{"type":"strong"}]},{"text":" - Use ","type":"text"},{"text":"context.getRemainingTimeInMillis()","type":"text","marks":[{"type":"code_inline"}]},{"text":" for long operations","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Security Considerations","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Never hardcode credentials; use IAM roles and environment variables","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Input Validation for Event Data","type":"text","marks":[{"type":"strong"}]},{"text":": All incoming event data (API Gateway request bodies, S3 event objects, SQS message bodies) is untrusted external content; always validate and sanitize before processing to prevent injection attacks","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Content Sanitization","type":"text","marks":[{"type":"strong"}]},{"text":": When processing S3 objects or SQS message payloads, treat the content as untrusted third-party data; apply appropriate validation, schema checks, and sanitization before acting on it","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Validate all input data","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use least privilege IAM policies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Enable CloudTrail for audit logging","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Sanitize logs to avoid leaking sensitive data","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"References","type":"text"}]},{"type":"paragraph","content":[{"text":"For detailed guidance on specific topics:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NestJS Lambda","type":"text","marks":[{"type":"link","attrs":{"href":"references/nestjs-lambda.md","title":null}},{"type":"strong"}]},{"text":" - Complete NestJS setup, dependency injection, Express/Fastify adapters","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Raw TypeScript Lambda","type":"text","marks":[{"type":"link","attrs":{"href":"references/raw-typescript-lambda.md","title":null}},{"type":"strong"}]},{"text":" - Minimal handler patterns, bundling, tree shaking","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Serverless Config","type":"text","marks":[{"type":"link","attrs":{"href":"references/serverless-config.md","title":null}},{"type":"strong"}]},{"text":" - Serverless Framework and SAM configuration","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Serverless Deployment","type":"text","marks":[{"type":"link","attrs":{"href":"references/serverless-deployment.md","title":null}},{"type":"strong"}]},{"text":" - CI/CD pipelines, environment management","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Testing","type":"text","marks":[{"type":"link","attrs":{"href":"references/testing.md","title":null}},{"type":"strong"}]},{"text":" - Jest, integration testing, SAM Local","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Examples","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Example 1: Create a NestJS REST API","type":"text"}]},{"type":"paragraph","content":[{"text":"Input:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"Create a TypeScript Lambda REST API using NestJS for a todo application","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"Process:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Initialize NestJS project with ","type":"text"},{"text":"nest new","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Install Lambda dependencies: ","type":"text"},{"text":"@codegenie/serverless-express","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"aws-lambda","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create ","type":"text"},{"text":"lambda.ts","type":"text","marks":[{"type":"code_inline"}]},{"text":" entry point with Express adapter","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configure ","type":"text"},{"text":"serverless.yml","type":"text","marks":[{"type":"code_inline"}]},{"text":" with API Gateway events","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Deploy with Serverless Framework","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Validation:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run ","type":"text"},{"text":"serverless invoke local -f api","type":"text","marks":[{"type":"code_inline"}]},{"text":" - verify handler works","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check bundle size \u003c 250MB","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test deployed endpoint returns 200 OK","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Output:","type":"text","marks":[{"type":"strong"}]},{"text":" NestJS project with REST API, DynamoDB integration, deployment config","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Example 2: Create a Raw TypeScript Lambda","type":"text"}]},{"type":"paragraph","content":[{"text":"Input:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"Create a minimal TypeScript Lambda function with optimal cold start","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"Process:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Set up TypeScript project with esbuild","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create handler with proper AWS types","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configure minimal dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Set up SAM or Serverless deployment","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Optimize bundle size with tree shaking","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Validation:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run ","type":"text"},{"text":"sam local invoke","type":"text","marks":[{"type":"code_inline"}]},{"text":" - test locally before deploying","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verify bundle \u003c 50KB with ","type":"text"},{"text":"du -sh dist/","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Confirm cold start \u003c 100ms via CloudWatch","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Output:","type":"text","marks":[{"type":"strong"}]},{"text":" Minimal TypeScript Lambda, bundle \u003c 50KB, cold start \u003c 100ms","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Example 3: Deploy with GitHub Actions","type":"text"}]},{"type":"paragraph","content":[{"text":"Input:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"Configure CI/CD for TypeScript Lambda with SAM","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"Process:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create GitHub Actions workflow","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Set up Node.js environment","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run tests with Jest","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Bundle with esbuild","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Deploy with SAM","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Validation:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verify CI pipeline runs ","type":"text"},{"text":"npm test","type":"text","marks":[{"type":"code_inline"}]},{"text":" successfully","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Confirm ","type":"text"},{"text":"sam validate","type":"text","marks":[{"type":"code_inline"}]},{"text":" passes in pipeline","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check CloudFormation stack created successfully","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Output:","type":"text","marks":[{"type":"strong"}]},{"text":" GitHub Actions workflow, multi-stage pipeline, test automation","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Version","type":"text"}]},{"type":"paragraph","content":[{"text":"Version: 1.0.0","type":"text"}]}]},"metadata":{"date":"2026-11-02","name":"aws-lambda-typescript-integration","author":"@skillopedia","source":{"stars":366,"repo_name":"developer-kit","origin_url":"https://github.com/giuseppe-trisciuoglio/developer-kit/blob/HEAD/plugins/developer-kit-typescript/skills/aws-lambda-typescript-integration/SKILL.md","repo_owner":"giuseppe-trisciuoglio","body_sha256":"223c7cc0019b5f6f02d754cfdde2278ddcb70c32b86bd1c73031f451fa36e1f1","cluster_key":"8215eb973918be0d6d49439d508ab1cb649347769a43b3147ed0da37730e8ea5","clean_bundle":{"format":"clean-skill-bundle-v1","source":"giuseppe-trisciuoglio/developer-kit/plugins/developer-kit-typescript/skills/aws-lambda-typescript-integration/SKILL.md","text_bytes":106175,"source_commit":"fe73fb33a09ee6562eeec7415a3f9a3bcf795177","skills_sh_rank":5636,"attachment_count":7,"text_attachments":7,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"plugins/developer-kit-typescript/skills/aws-lambda-typescript-integration/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"devops-infrastructure","category_label":"DevOps"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"devops-infrastructure","import_tag":"skills-sh-top20k-2026-11","description":"Provides AWS Lambda integration patterns for TypeScript with cold start optimization. Use when creating or deploying TypeScript Lambda functions, choosing between NestJS framework and raw TypeScript approaches, optimizing cold starts, configuring API Gateway or ALB integration, or implementing serverless TypeScript applications. Triggers include \"create lambda typescript\", \"deploy typescript lambda\", \"nestjs lambda aws\", \"raw typescript lambda\", \"aws lambda typescript performance\".","allowed-tools":"Read, Write, Edit, Glob, Grep, Bash"}},"renderedAt":1793665857315}

AWS Lambda TypeScript Integration Patterns for creating high-performance AWS Lambda functions in TypeScript with optimized cold starts. Overview Two approaches for TypeScript Lambda: 1. NestJS Framework - Dependency injection, modular architecture, larger bundle (100KB+) 2. Raw TypeScript - Minimal overhead, smaller bundle (<50KB), maximum control Both support API Gateway and ALB integration. When to Use - Creating new Lambda functions in TypeScript - Optimizing cold start performance - Choosing between NestJS and minimal TypeScript - Configuring API Gateway or ALB integration - Setting up CI…