An open API service indexing awesome lists of open source software.

https://github.com/geoffdutton/lambda-proxy-utils

Lambda event helpers for AWS API Gateway lambda-proxy integration
https://github.com/geoffdutton/lambda-proxy-utils

Last synced: 12 months ago
JSON representation

Lambda event helpers for AWS API Gateway lambda-proxy integration

Awesome Lists containing this project

README

          

# lambda-proxy-utils
[![npm version](https://badge.fury.io/js/lambda-proxy-utils.svg)](https://badge.fury.io/js/lambda-proxy-utils)
[![Build Status](https://travis-ci.org/geoffdutton/lambda-proxy-utils.svg?branch=master)](https://travis-ci.org/geoffdutton/lambda-proxy-utils)
[![Coverage Status](https://coveralls.io/repos/github/geoffdutton/lambda-proxy-utils/badge.svg?branch=master)](https://coveralls.io/github/geoffdutton/lambda-proxy-utils?branch=master)
[![Dependency Status](https://david-dm.org/geoffdutton/lambda-proxy-utils.svg)](https://david-dm.org/geoffdutton/lambda-proxy-utils/)
[![Standard - JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](http://standardjs.com/)

Lambda event helpers for AWS API Gateway lambda-proxy integration

## Install
```
npm install --save lambda-proxy-utils
```

## Update for version 2+
Node 4 is unsupported.

## Update for version 1.4.0
AWS Lambda doesn't allow arrays for headers, so this is the hack way of returning multiple cookies per this thread:
https://forums.aws.amazon.com/thread.jspa?threadID=205782

Basically you need to set multiple varations of `Set-Cookie` on the headers response object passed to the lambda callback like:
```javascript
const response = {
body: 'something',
headers: {
'Content-Type': 'text/plain',
'Set-Cookie': 'some=cookie; Path=/',
'Set-cookie': 'another=cookie; Path=/',
'SEt-cookie': 'and_another=cookie; Path=/',
},
statusCode: 200
}
```

Using [binary-case](https://www.npmjs.com/package/binary-case), we can generate 512 variations of `Set-Cookie`, so there's a hard limit, but hopefully you aren't setting 512 cookies.

## Request
Takes an [API Gateway](http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on-proxy-resource) lambda proxy integration event and returns an object that is similar to an express.js Request object.
```javascript
// Example API Gateway proxy integration event passed to lambda
{
"resource": "/api/pipe/{pathParam}",
"path": "/api/pipe/hooray/",
"httpMethod": "GET",
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, sdch, br",
"Accept-Language": "en-US,en;q=0.8",
"Cache-Control": "no-cache",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Cookie": "some=thing; testbool=false; testnull=null",
"Host": "services.cheekyroad.com",
"Pragma": "no-cache",
"Referer": "https://cheekyroad.com/paht/?cool=true",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36",
"Via": "1.1 1a1a1a1.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "2b2b2b2b2==",
"X-Forwarded-For": "111.111.111.111, 222.222.222.222",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"queryStringParameters": {
"et": "something"
},
"pathParameters": {
"pathParam": "hooray"
},
"stageVariables": null,
"requestContext": {
"accountId": "111111111111",
"resourceId": "blah",
"stage": "dev",
"requestId": "08e3e2d0-daca-11e6-8d84-394b4374a71a",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"apiKey": null,
"sourceIp": "111.111.111.111",
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36",
"user": null
},
"resourcePath": "/api/pipe/{pathParam}",
"httpMethod": "GET",
"apiId": "cdcd4"
},
"body": null,
"isBase64Encoded": false
}

const Request = require('lambda-proxy-utils').Request

module.exports.lambdaHandler = function(event, context, callback) {
const req = new Request(event)
req.ip // '111.111.111.111'
req.userAgent // 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36'

// Get's a field value in the order of query string param -> cookie -> header
req.get('host') // 'services.cheekyroad.com'
req.get('testnull') // null

// Or be specific
req.getHeader('x-forwarded-proto') // 'https'

// Check the type
req.is('html') // false

// Get an AWS API Gateway requestContext property
req.context('requestId') // '08e3e2d0-daca-11e6-8d84-394b4374a71a'

// Get the unmodified Lambda Proxy event
req.getLambdaEvent()
}
```

## Response
Creates an express.js-like Response object, and outputs the API Gateway [response format](http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-simple-proxy-for-lambda-output-format)
```javascript
const Response = require('lambda-proxy-utils').Response

module.exports.lambdaHandler = function(event, context, callback) {
const res = new Response()
// stringifies objects and set correct content type header
callback(null, res.send({ some: 'object' }))
/*
{
statusCode: 200,
headers: {
'Content-Type': 'application/json'
},
body: '{ "some": "object" }'
}
*/

// Support for CORS
const res = new Response({ cors: true })
callback(null, res.send({ some: 'object' }))
/*
{
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: '{ "some": "object" }'
}
*/

// Add a cookie
const res = new Response()
res.cookie('cookie', 'monster')
callback(null, res.send({ some: 'object' }))
/*
{
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'cookie=monster; Path=/'
},
body: '{ "some": "object" }'
}
*/

// Add a header
const res = new Response()
res.set('X-Random-Header', 1)
callback(null, res.send({ some: 'object' }))
/*
{
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'X-Random-Header': '1'
},
body: '{ "some": "object" }'
}
*/
}
```

## Contributing
I'd happily welcome pull requests. I've chosen to use Standard as the style with a few slight modifications. I'd like to keep the code coverage as high as possible.

## Credits
I borrowed a lot from [express](https://github.com/expressjs/express)