Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introducing Middy, Node.js middleware engine for AWS Lambda (FrontConf Munich 2017 — Lightning talk)

Introducing Middy, Node.js middleware engine for AWS Lambda (FrontConf Munich 2017 — Lightning talk)

One of the main strengths of serverless and AWS Lambda is that, from a developer perspective, your focus is mostly shifted toward implementing business logic. Anyway, when you are writing an handler, you still have to deal with some common technical concerns outside business logic, like input parsing and validation, output serialization, error handling, etc. Very often, all this necessary code ends up polluting the pure business logic code in your handlers, making the code harder to read and to maintain. In other contexts, like generic web frameworks (express, fastify, hapi, etc.), this problem has been solved using the middleware pattern. Middy brings the middleware pattern into AWS Lambda making it easier to focus on business logic and reuse the boilerplate code across different functions.

Luciano Mammino

December 09, 2017
Tweet

More Decks by Luciano Mammino

Other Decks in Technology

Transcript

  1. exports.myLambda = function ( event, context, callback ) { //

    get input from event and context // use callback to return output or errors } Anatomy of a Node.js lambda on AWS 5
  2. (event, context, callback) => { // decrypt environment variables with

    KMS // deserialize the content of the event // validate input, authentication, authorization // REAL BUSINESS LOGIC // (process input, generate output) // validate output // serialize response // handle errors } A typical "REAL" Lambda function LOTS of BOILERPLATE 6
  3. Usage const middy = require('middy') const { middleware1, middleware2, middleware3

    } = require('middy/middlewares') const originalHandler = (event, context, callback) => { /* your business logic */ } const handler = middy(originalHandler) handler .use(middleware1()) .use(middleware2()) .use(middleware3()) module.exports = { handler } 9
  4. const middy = require('middy') const { urlEncodedBodyParser, validator, httpErrorHandler }

    = require('middy/middlewares') const processPaymentHandler = (event, context, callback) => { const { creditCardNumber, expiryMonth, expiryYear, cvc, nameOnCard, amount } = event.body // do stuff with this data ... return callback(null, { result: 'success', message: 'payment processed correctly'} ) } const inputSchema = { // define validation schema here ... } const handler = middy(processPaymentHandler) .use(urlEncodedBodyParser()) .use(validator(inputSchema)) .use(httpErrorHandler()) module.exports = { handler } 10
  5. Why? Simplify code Reusability input parsing input & output validation

    output serialization error handling ... Focus MORE on business logic 11
  6. Execution order 1. middleware1 (before) 2. middleware2 (before) 3. middleware3

    (before) 4. handler 5. middleware3 (after) 6. middleware2 (after) 7. middleware1 (after) 13
  7. When an error happens... Flow is stopped First middleware implementing

    `onError` gets control It can choose to handle the error, or delegate it to the next handler If the error is handler a response is returned If the error is not handled the execution fails reporting the unhandled error 14
  8. Writing a middleware const myMiddleware = (config) => { //

    might set default options in config return ({ before: (handler, next) => { // might read options from `config` }, after: (handler, next) => { // might read options from `config` }, onError: (handler, next) => { // might read options from `config` } }) } module.exports = myMiddleware 15
  9. Inline middlewares const middy = require('middy') const handler = middy((event,

    context, callback) => { // do stuff }) handler.before((handler, next) => { // do something in the before phase next() }) handler.after((handler, next) => { // do something in the after phase next() }) handler.onError((handler, next) => { // do something in the on error phase next() }) module.exports = { handler } 16
  10. Currently availble middlewares JSON Body Parser Url Encoded Body Parser

    Validator HTTP Error Handler CORS S3 Key Normalizer Do Not Wait for event loop Support for async/await handlers (just return, don't need to use callback) XML Body parser API Gateway Event normalizer In development 17