Here’s an example: https://middy.js.org/docs/intro/getting-started
import middy from '@middy/core'
import middleware1 from 'sample-middleware1'
import middleware2 from 'sample-middleware2'
import middleware3 from 'sample-middleware3'
const lambdaHandler = (event, context) => {
/* your business logic */
}
export const handler = middy(lambdaHandler)
handler
.use(middleware1())
.use(middleware2())
.use(middleware3())
Why export handler
first, and then further configure it in the same file in which it’s been defined in?
- Is there ever a good reason to use this pattern?
- Also does Node normalize the exports, by which I mean ignoring where export statements are located and when someone imports a package, Node somehow ensures all the exports occur after everything else?
Oddly enough they use different patterns in different examples. Here’s another one:
// import core
import middy from '@middy/core' // esm Node v14+
//const middy = require('@middy/core') // commonjs Node v12+
// import some middlewares
import jsonBodyParser from '@middy/http-json-body-parser'
import httpErrorHandler from '@middy/http-error-handler'
import validator from '@middy/validator'
// This is your common handler, in no way different than what you are used to doing every day in AWS Lambda
const lambdaHandler = async (event, context) => {
// we don't need to deserialize the body ourself as a middleware will be used to do that
const { creditCardNumber, expiryMonth, expiryYear, cvc, nameOnCard, amount } = event.body
// do stuff with this data
// ...
const response = { result: 'success', message: 'payment processed correctly'}
return {statusCode: 200, body: JSON.stringify(response)}
}
// Notice that in the handler you only added base business logic (no deserialization,
// validation or error handler), we will add the rest with middlewares
const eventSchema = {
type: 'object',
properties: {
body: {
type: 'object',
properties: {
creditCardNumber: { type: 'string', minLength: 12, maxLength: 19, pattern: '\\d+' },
expiryMonth: { type: 'integer', minimum: 1, maximum: 12 },
expiryYear: { type: 'integer', minimum: 2017, maximum: 2027 },
cvc: { type: 'string', minLength: 3, maxLength: 4, pattern: '\\d+' },
nameOnCard: { type: 'string' },
amount: { type: 'number' }
},
required: ['creditCardNumber'] // Insert here all required event properties
}
}
}
// Let's "middyfy" our handler, then we will be able to attach middlewares to it
const handler = middy()
.use(jsonBodyParser()) // parses the request body when it's a JSON and converts it to an object
.use(validator({eventSchema})) // validates the input
.use(httpErrorHandler()) // handles common http errors and returns proper responses
.handler(lambdaHandler)