Giter Site home page Giter Site logo

dbartholomae / lambda-middleware Goto Github PK

View Code? Open in Web Editor NEW
151.0 10.0 18.0 1.38 MB

A collection of middleware for AWS lambda functions.

Home Page: https://dbartholomae.github.io/lambda-middleware/

License: MIT License

TypeScript 84.70% JavaScript 10.05% Raku 2.66% Perl 2.58%
aws lambda middleware lambda-middleware hacktoberfest

lambda-middleware's Introduction

@lambda-middleware

open issues debug build status codecov CLA assistant

This monorepo is a collection of middleware for AWS lambda functions.

Middlewares

Other packages

Furthermore there is utility collection available at @lambda-middleware/utils.downloads

Usage

Each middleware is a higher-order function that can be wrapped around the handler function.

export const handler = someMiddleware()(() => {
  return {
    body: '',
    statusCode: 200
  }
})

Each middleware is build as

(options) => (handler) => (event, context) => Response

This means that middleware can be composed and piped like any other function with only one parameter (the handler). This library contains a helper for composing, but any other implementation should work as well.

export const handler = compose(
  someMiddleware(),
  someOtherMiddleware(),
  aThirdMiddleware()
)(() => {
  return {
    body: '',
    statusCode: 200
  }
})

There's a known issue with TypeScript that pipe and compose functions cannot infer types correctly if the innermost function is generic (in this case the last argument to compose). If you use TypeScript in strict mode, you can instead use the composeHandler function exported from @lambda-middleware/compose:

export const handler = composeHandler(
  someMiddleware(),
  someOtherMiddleware(),
  aThirdMiddleware(),
  () => {
    return {
      body: '',
      statusCode: 200
    }
  }
)

Composing middleware is equivalent to calling it nested:

export const handler =
  someMiddleware()(
    someOtherMiddleware()(
      aThirdMiddleware()(() => {
        return {
          body: '',
          statusCode: 200
        }
      })
    )
  )

The order of composition can be relevant. When using a helper to do the composition, check, in which order the functions are applied. Most of the time TypeScript should be able to warn you, if the order is wrong.

Imagine middleware as an onion around your function: The outermost middleware will get called first before the handler starts, and last after the handler finishes or throws an error. In our example above the order in which middleware gets executed therefore would be:

someMiddleware
  someOtherMiddleware
    aThirdMiddleware
      the handler
    aThirdMiddleware
  someOtherMiddleware
someMiddleware

This means that middleware which transforms the input for the handler will be executed top to bottom, while middleware that transforms the response will be called bottom to top.

Writing your own middleware

If you want to write your own middleware, check the existing examples and feel free to borrow some of the tests for inspiration. The general idea for a middleware is the following:

const myMiddleware = (optionsForMyMiddleware) => (handler) => async (event, context) => {
  try {
    const modifiedEvent = doSomethingBeforeCallingTheHandler(event)
    const response = await handler(modifiedEvent, context)
    const modifiedResponse = doSomethingAfterCallingTheHandler(response)
    return modifiedResponse
  } catch (error) {
    const modifiedError = doSomethingInCaseOfAnError(error)
    throw modifiedError
  }
}

Usually the same middleware should not need to do something before the handler, after the handler and on error. Creating separated middlewares for these cases keeps them more versatile. But cases that require multiple steps are supported as well.

Since the middlewares only uses function composition, TypeScript can offer extensive typing support to let you know how the middleware changed. When adding your own middleware it is recommended to use generics to avoid losing type information.

Instead of

const bodyParser = () =>
  (handler: PromiseHandler<Omit<APIGatewayProxyEvent, body> & { body: object}, APIGatewayProxyResult>): PromiseHandler<APIGatewayProxyEvent, APIGatewayProxyResult> =>
  async (event: E, context: Context) => {
  return handler({ ...event, body: JSON.parse(event.body) }, context)
}

use

const bodyParser = () =>
  <E extends APIGatewayProxyEvent>(handler: PromiseHandler<Omit<E, body> & { body: object}, APIGatewayProxyResult>): PromiseHandler<E, APIGatewayProxyResult> =>
  async (event: E, context: Context) => {
  return handler({ ...event, body: JSON.parse(event.body) }, context)
}

so that if multiple middlewares change the event, the resulting type will have all changes and not just the latest.

Contributing

If you want to contribute to the project, please read our contributing guidelines first.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.