Skip to content

evilkiwi/lamware

Repository files navigation

NPM Discord GPL-3.0-only

AWS Lambda Middleware Pattern (NodeJS)

Lamware is a simple design pattern based on middleware for AWS Lambda. Lambda, like other Cloud Function platforms, is executed by a request - which could be from anything like a queue (SQS) to a HTTP request. Since Lambda focusses on business logic, setting things up before-hand can be quite tedious.

Using a middleware pattern means your function is slightly delayed in recieving the event whilst Lamware runs various logic to set things up (in parallel, where possible). For example, you could have middleware set up to do things like:

  • Pull Secrets from Secrets Manager/external service
  • Fetch JSON config from AppConfig
  • Exit early if this was a Warming event from CloudWatch
  • Automate some Tracing bootstrap
  • Set-up some best practises (Like callbackWaitsForEmptyEventLoop)

Installation

This package is available via NPM:

yarn add @lamware/core

# or

npm install @lamware/core

We maintain and ship various middlewares for public use - you can install them too!

Usage

We have Documentation available here, and you can check out the example folder for a fully-featured example with the AWS CDK stack to deploy it.

import { powertoolsTracing } from '@lamware/powertools-tracing';
import { powertoolsLogger } from '@lamware/powertools-logger';
import type { APIGatewayProxyHandlerV2 } from 'aws-lambda';
import { doNotWait } from '@lamware/do-not-wait';
import { appconfig } from '@lamware/appconfig';
import { sentry } from '@lamware/sentry';
import { warmer } from '@lamware/warmer';
import { lamware } from '@lamware/core';

const { handler } = lamware<APIGatewayProxyHandlerV2<any>>()
  .use(doNotWait())
  .use(powertoolsTracing({
    serviceName: 'lamware-example',
  }))
  .use(powertoolsLogger({
    serviceName: 'lamware-example',
    logLevel: 'DEBUG',
  }))
  .use(appconfig<{ hello: string }>({
    app: 'evilkiwi-lamware-example',
    env: 'production',
    config: 'production',
  }))
  .use(sentry({
    config: {
      dsn: 'https://[email protected]/6270000',
    },
  }))
  .use(warmer())
  .execute(async ({ state }) => {
    return {
      statusCode: 200,
      body: JSON.stringify({
        hello: 'world',
        appconfig: state.config,
      }),
    };
  });

export { handler };