Closed
Description
Discussed in #3449
Originally posted by cyrildewit December 30, 2024
Hi, I am implementing a Lambda handler that will consume a SQS queue filled with S3 event notifications. I expected that S3SqsEventNotificationSchema
would also validate and parse the payload of the S3 Event Notification within the SQS Message, but that is currently not the case.
Here's a copy of the official schemas for easy reference source:
const S3SqsEventNotificationSchema = z.object({
Records: z.array(S3SqsEventNotificationRecordSchema),
});
const S3SqsEventNotificationRecordSchema = SqsRecordSchema.extend({
body: z.string(),
});
I wonder if this design decision was made on purpose?
I have solved it by creating a custom version of S3SqsEventNotificationSchema
, like so:
const extendedS3SqsEventNotificationSchema = S3SqsEventNotificationSchema.extend({
Records: z.array(SqsRecordSchema.extend({
body: JSONStringified(S3Schema),
})),
});
type ExtendedS3SqsEventNotification = z.infer<typeof extendedS3SqsEventNotificationSchema>;
Full code example for reference:
import type { SQSHandler } from 'aws-lambda';
import middy from '@middy/core';
import { Logger } from '@aws-lambda-powertools/logger';
import { injectLambdaContext } from '@aws-lambda-powertools/logger/middleware';
import { parser } from '@aws-lambda-powertools/parser/middleware';
import {
S3Schema,
S3SqsEventNotificationSchema,
SqsRecordSchema,
} from '@aws-lambda-powertools/parser/schemas';
import { JSONStringified } from '@aws-lambda-powertools/parser/helpers';
import { BatchProcessor, EventType, processPartialResponse } from '@aws-lambda-powertools/batch';
import { z } from 'zod';
const processor = new BatchProcessor(EventType.SQS);
const logger = new Logger({
logLevel: 'debug',
});
const extendedS3SqsEventNotificationSchema = S3SqsEventNotificationSchema.extend({
Records: z.array(SqsRecordSchema.extend({
body: JSONStringified(S3Schema),
})),
});
type ExtendedS3SqsEventNotification = z.infer<typeof extendedS3SqsEventNotificationSchema>;
const recordHandler = async (record: ExtendedS3SqsEventNotification['Records'][number]): Promise<void> => {
logger.debug('S3 Event Records', {
s3EventRecords: record.body.Records,
});
};
const lambdaSqsHandler: SQSHandler = async (event, context) =>
processPartialResponse(event, recordHandler, processor, {
context,
});
export const handler = middy(lambdaSqsHandler)
.use(injectLambdaContext(logger, { logEvent: true }))
.use(parser({ schema: extendedS3SqsEventNotificationSchema }));
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Shipped