S3 Triggers
defineS3Handler creates Lambda handlers triggered by S3 object events. Import from @mantleframework/core.
The factory normalises both direct (S3→Lambda) and EventBridge-routed (S3→EventBridge→Lambda) event shapes into the same S3RecordContext so your handler code is identical regardless of trigger mode.
Pattern
import { defineS3Handler } from '@mantleframework/core'
import { getObject } from '@mantleframework/aws'
const s3 = defineS3Handler({
bucket: 'uploads',
operationName: 'ProcessUpload',
})
export const handler = s3(async (record, metadata) => {
const { bucket, key, size } = record
const object = await getObject({ Bucket: bucket, Key: key })
await processUpload(object.Body, key)
})Options
| Option | Type | Default | Description |
|---|---|---|---|
bucket | string | -- | Bucket name — matches config.storage[].name for CLI infra wiring |
trigger | 'direct' | 'eventbridge' | 'direct' | Trigger mechanism |
operationName | string | function name | Name for metrics and tracing |
logging | LoggingConfig | -- | Fixture logging configuration |
timeout | number | -- | Lambda timeout in seconds |
memorySize | number | 128 | Lambda memory in MB |
reservedConcurrency | number | -- | Reserved concurrent executions |
ephemeralStorage | number | 512 | Ephemeral storage in MB |
deadLetterQueue | boolean | { targetArn? } | -- | true = auto-generate SQS DLQ |
retryAttempts | number | -- | Max retry attempts (0-2) |
Per-Record Callback
The inner handler is called once per S3 record and receives S3RecordContext:
interface S3RecordContext {
bucket: string // S3 bucket name
key: string // S3 object key (URL-decoded)
size: number // Object size in bytes
eventName: string // e.g. 'ObjectCreated:Put'
eventTime: string // ISO timestamp of the event
rawRecord: S3EventRecord
}The second argument is WrapperMetadata:
interface WrapperMetadata {
traceId: string
correlationId: string
}Trigger Modes
Direct (S3 → Lambda)
The default. S3 invokes Lambda directly via a bucket notification configuration.
const s3 = defineS3Handler({ bucket: 'uploads', trigger: 'direct' })EventBridge (S3 → EventBridge → Lambda)
S3 emits events to EventBridge, which routes them to Lambda. Useful when multiple consumers need to react to the same S3 event, or when you want centralised event routing.
const s3 = defineS3Handler({ bucket: 'uploads', trigger: 'eventbridge' })The handler code is identical in both modes — the factory normalises the event shape.
Bucket Config
The bucket option must match a storage entry in mantle.config.ts:
export default defineConfig({
storage: [
{ name: 'uploads' },
{ name: 'exports' },
],
})The CLI uses this to wire S3 notifications and IAM permissions automatically.
File Location
S3 handlers live under src/lambdas/s3/<HandlerName>/index.ts:
src/lambdas/s3/
ProcessUpload/
index.ts
ProcessExport/
index.tsSee Also
- Handler Patterns — overview of all handler types
- SQS Queue Handlers — queue-based processing