Giter Club home page Giter Club logo

lambda-request-handler's Introduction

lambda-request-handler

An npm module that allows your Node.js web applications to be deployed as an AWS Lambda function and invoked in response to API Gateway, HTTP API, or Application Load Balancer requests.

Build Status

The list of supported frameworks matches in-process-request

  • Express.js v3
  • Express.js v4
  • Express.js v5
  • Apollo Server v2
  • Hapi v19 (only supported in nodejs12.x runtime)
  • Hapi v20 (only supported in nodejs12.x runtime)
  • NestJS v7
  • Connect v3
  • Koa v2
  • Polka
  • Fastify v3

Inspired by aws-serverless-express

It supports nodejs10.x and nodejs12.x execution environments.

The main differences between this module and aws-serverless-express are

  • It's using in-process-request module to execute app handlers in-process without having to start background http server
  • Simpler setup as it doesn't require managing the internal http server
  • Support for applications that require asynchronous setup (for example reading config from network, or decrypting secrets from KMS)
  • It's faster, because it doesn't need to pass the request to the internal server through the unix socket
  • It's free from issues caused by limits in Node.js http module such as header size limit

The handler supports events from the following sources:

Demo app

There's a demo app showcasing the features of this library available here

Usage

The default export of lambda-request-handler is a function that takes an application handler (i.e. Express.js app instance) as an argument and returns an AWS Lambda handler function.

An additional header is injected into the request

  • x-aws-lambda-request-id - AWS Lambda Request Id
$ npm install lambda-request-handler

Express.js

const express = require('express')
const lambdaRequestHandler = require('lambda-request-handler')

const app = express()

app.get('/user/:id', (req, res) => {
  res.json({
    id: req.params.id,
    lambdaRequestId: req.header('x-aws-lambda-request-id')
    name: 'John'
  })
})

const handler = lambdaRequestHandler(app)

module.exports = { handler }

If the above file in your Lambda source was called index.js then the name of the handler in the Lambda configuration is index.handler

Advanced example with asynchronous setup

Sometimes the application needs to read configuration from remote source before it can start processing requests. For example it may need to decrypt some secrets managed by KMS. For this use case a special helper deferred has been provided. It takes a factory function which returns a Promise that resolves to the app instance. The factory function will be called only once.

const lambdaRequestHandler = require("lambda-request-handler")
const AWS = require("aws-sdk")
const express = require("express")

const createApp = (secret) => {
  const app = express()
  app.get("/secret", (req, res) => {
    res.json({
      secret: secret,
    })
  })
}

const myAppPromise = async () => {
  const kms = new AWS.KMS()
  const data = await kms
    .decrypt({
      CiphertextBlob: Buffer.from(process.env.ENCRYPTED_SECRET, "base64"),
    })
    .promise()
  const secret = data.Plaintext.toString("ascii")
  return createApp(secret)
}

const handler = lambdaRequestHandler.deferred(myAppPromise)

module.exports = { handler }

Hapi

Please note that Hapi v19 dropped support for Node v10. The only AWS Lambda runtime that supports it is nodejs12.x.

const Hapi = require("@hapi/hapi")
const lambdaRequestHandler = require("lambda-request-handler")

// create custom listener for Hapi
const myListener = new lambdaRequestHandler.HapiListener()

// Pass the custom listener to Hapi.server
const server = Hapi.server({
  listener: myListener,
})

server.route({
  method: "GET",
  path: "/",
  handler: (_request: any, _h: any) => {
    return "Hello World!"
  },
})

const myAppPromise = async () => {
  //wait for the server to initialize
  await server.start()
  // return the request listener function
  return myListener.handler
}

const handler = lambdaRequestHandler.deferred(myAppPromise)

module.exports = { handler }

If the above file in your Lambda source was called index.js then the name of the handler in the Lambda configuration is index.handler

NestJS

This example is in Typescript

import lambdaRequestHandler from "lambda-request-handler"

import { NestFactory } from "@nestjs/core"
import { Module, Get, Controller } from "@nestjs/common"
import { NestExpressApplication } from "@nestjs/platform-express"

@Controller()
class AppController {
  @Get()
  render() {
    return { hello: "world" }
  }
}

@Module({
  imports: [],
  controllers: [AppController],
})
class AppModule {}

const getApp = async () => {
  const app = await NestFactory.create<NestExpressApplication>(AppModule)

  return await lambdaRequestHandler.nestHandler(app)
}

const handler = lambdaRequestHandler.deferred(getApp)

module.exports = { handler }

If the above file in your Lambda source was called index.ts, compiled to index.js then the name of the handler in the Lambda configuration is index.handler

Polka

const polka = require('polka')
const lambdaRequestHandler = require('lambda-request-handler')

const app = polka()

app.get('/user/:id', (req, res) => {
  res.json({
    id: req.params.id,
    lambdaRequestId: req.header('x-aws-lambda-request-id')
    name: 'John'
  })
})

const handler = lambdaRequestHandler(app.handler.bind(app))

module.exports = { handler }

If the above file in your Lambda source was called index.js then the name of the handler in the Lambda configuration is index.handler

lambda-request-handler's People

Contributors

benurb avatar dependabot[bot] avatar janaz avatar jlarmstrongiv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

sueddeutsche

lambda-request-handler's Issues

Add an example app

Create an example Express.js app that's using this module for deployment.

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.