Recently I had the necessity to store the request payloads hitting our lambdas in a S3 bucket (do not ask me why :D).
After a quick investigations, I decided that the best solution was achieve this on a middleware and I started to research was was the best approach to add a middleware to a lambda function. I worked with middlewares on Node for years, but it was the first time I had to do it on a lambda function.
The best tool I found is Middy, a pretty powerful but extremely user friendly package.
The implementation is quite straightforward:
Without Middy, a Lambda function could look like the following:
export const handler (event, context) => {
// BOILERPLATE
// E.g. decrypt environment variables with KMS
// deserialize the content of the event
// validate input, authentication, authorization
// REAL BUSINESS LOGIC
let response = doSomethingUsefulWith(event)
// MORE BOILERPLATE
// E.g.
// validate output
// serialize response
// handle errors
return response
}
However, Middy
allow us to drastically simplify our code:
import middy from "@middy/core";
const lambdaHandler = (event, context) => {
// REAL BUSINESS LOGIC
return doSomethingUsefulWith(event);
};
export const handler = middy(lambdaHandler)
.use(/* Your own behaviour in a reusable fashion */)
.use(/* logging and tracing */)
.use(/* input validation */)
.use(/* authentication */)
.use(/* error handling */)
.use(/* other behaviour */);
The pseudo code of the solution I came up with, it’s the following:
// s3_utils.ts
Export default saveOnS3 (payload: string): void => {
// save to S3
}
// Function.ts
import middy from '@middy/core'
import saveOnS3 from '../s3_utils'
const buildHandlerWithDefaultMiddleware(
baseHandler: (event: APIGatewayProxyEvent, context: MiddlewareContext) => Promise<APIGatewayProxyResult>,
) {
return middy(baseHandler)
.use(saveOnS3(event.body))
.use(furtherLogic())
.user(evenFurtherLogic())
It’s a quite straightforward implementation. However, if you have any question or feedback, please reach out.
Until the next time, keep on coding!