npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

aws-api-lambda-scaffold-js

v2.3.0

Published

Micro framework for AWS API Gateway integration with AWS Lambda functions allowing you to use a Lambda like a micro service server

Downloads

98

Readme

AWS API Gateway and Lambda function integration scaffolding for Node.js

Project setup

You need to install AWS-CLI. (pip install --upgrade --user awscli)

You need to setup AWS-CLI with your credentials. (aws configure)

You need to install mocha for running tests (npm install --global mocha)

Features

  • Routing
  • Response transformation
  • Layered middleware

What's new

v.2.0.0 - Added middleware, refactored code and project minification

API Gateway setup

Creating a new endpoint

When creating a new method for a resource endpoint check the "Use Lambda Proxy integration" checkbox to pass request data into the event object in the lambda function.

Lambda setup

Configuration

Select the Node.js 6+ Runtime

Lambda Node.js support: http://www.whatdoeslambdasupport.com/

Installation

Using npm

npm i aws-api-lambda-scaffold-js

Working with the framework

Main function

The main handler function should be defined in the index.js file and is the entry and exit point for the application.

Import the scaffold package:

const scaffold = require("aws-api-lambda-scaffold-js")

Or import the Router and Response classes directly

const Router = require("aws-api-lambda-scaffold-js").Router,
      Response = require("aws-api-lambda-scaffold-js").Response;

Program flow

Upon invoking the handler a Router instance should be created and passed event and context parameters. All of the routes that need to be handled need to be registered with the Router instance by invoking Router.route(path, method, handler). The Router will handle the request and invoked the provided callback when you invoke the Router.process(callback) method. If a route is not found the Router will throw an error.

To instantiate the Router:

const router = new scaffold.Router(event, context);

And when instantiating a Response or CustomResponse

return new scaffold.Response(body, statusCode, isBase64Encoded, headers)
const response = new scaffold.CustomResponse(headers, isBase64Encoded);

// Send the response
return response.send(body);

Both Response classes have a default header value of:

{"Content-type": "application/json"}

The benefits of using a custom response and passing it to the router is that you can share response data without having to write it multiple times.

To see an example Lambda function, view the demo.js file in the package directory.

Routes

To add a route to the router after instantiation use the following

router.route("/route/{param}", "GET", handler, [middleware, middleware]);

The route will match if the lambda is invoked trough API Gateway with the specified path, and the handler function will be invoked.

Route handler

The route handler is a function that will be invoked when a resource match is found. It will receive the request data object, which contains useful information which can be extracted from the event object and the execution callback that can be invoked for async functions. It will also be injected with the CustomResponse instance that is passed to Router.process(ctx, responseInstance) or a newly instantiated CustomResponse class if none is passed to Router.process(ctx, customResponseInstance).

function ({requestBody, queryStringParameters, pathParameters, headers, stageVariables, requestContext}, response, callback) {
    /** function body */
}

If the handler returns a value it must return a Response object with the following format

{
    "isBase64Encoded": Boolean,
    "statusCode": Number,
    "headers": {"key": "val"},
    "body": String
}

Or it should invoke the callback (ie. if the function is doing async work and has no return value). The handler should return a Response instance a CustomResponse.send(body) object.

Example API Gateway route test: http://i.imgur.com/dPkux1k.png

Basic directory structure we recommend is having a separate directory for all the route handlers. (You can see an example in the package directory)

Middleware

Middleware is one of those very flexible things allowing you to seperate your lambda properly by removing logging/authorization/etc... from your handler's business logic.

If your handlers run sync code, you need to return the next(request) or assign it to a variable and then return the code. In case of async handlers the middleware must NOT return anything if you want to proceed further, otherwise the framework will use the returned value as the lambda execution result.

Sync handler middleware

function ({requestBody, queryStringParameters, pathParameters, headers, stageVariables, requestContext}, responseInstance, next) {
    // If error you can return it and the execution will stop there
    if (error) {
        return response.send({success: false});
    }

    // If you want the middleware to resolve and progress invoke next(request);
    return next(request);
}

Async handler middleware

function ({requestBody, queryStringParameters, pathParameters, headers, stageVariables, requestContext}, responseInstance, next) {
    // If error you can return it and the execution will stop there
    if (error) {
        // End the lambda execution early due to an error by invoking the original callback to end lambda execution
        return request.callback(null, response.send({success: false}));
    }

    // If you want the middleware to resolve and progress invoke next(request);
    next(request);
}

Example usage can be found in the demo.js file.

Publishing your changes to the Lambda

Create a .lambda_contents file in your root directory (example .lambda_contents is located in the package directory), and add your lambda project files and folders separated by newlines.

When you want to apply changes to the lambda you can run the publish.sh script from the package directory.

./node_modules/aws-api-lambda-scaffold-js/publish.sh yourLambdaName

(Replace yourLambdaName with your Lambda function name)

It will automatically zip all of the files from the .lambda_contents file and push the changes to the lambda using aws-cli.

Running tests

To run tests you can execute npm run test which will run all mocha tests located in the test directory

Mocha docs: https://mochajs.org/

Misc

Webstorm js language help

Install assert-plus, node, mocha libraries to get code completion and help in WebStorm and enable nodejs coding assistance

Useful links

http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html

Example Lambda data availability

The Lambda handler is receiving three parameters: event, context and callback The event contains request data, context contains the lambda context and callback – You can use the optional callback to return information to the caller, otherwise return value is null. It should be invoked because it terminates the lambda function properly.

{
    "event": {
        "resource": "/hash",
        "path": "/hash",
        "httpMethod": "POST",
        "headers": null,
        "queryStringParameters": null,
        "pathParameters": null,
        "stageVariables": null,
        "requestContext": {
            "path": "/hash",
            "accountId": "123",
            "resourceId": "7kyb5s",
            "stage": "test-invoke-stage",
            "requestId": "test-invoke-request",
            "identity": {
                "cognitoIdentityPoolId": null,
                "accountId": "123",
                "cognitoIdentityId": null,
                "caller": "CALLER",
                "apiKey": "test-invoke-api-key",
                "sourceIp": "test-invoke-source-ip",
                "accessKey": "YOURACCESSKEY",
                "cognitoAuthenticationType": null,
                "cognitoAuthenticationProvider": null,
                "userArn": "arn:aws:iam::123:user/nenad-lukic",
                "userAgent": "Apache-HttpClient/4.5.x (Java/1.8.0_112)",
                "user": "123"
            },
            "resourcePath": "/hash",
            "httpMethod": "POST",
            "apiId": "123ijjk13"
        },
        "body": "{\n    \"email\": \"[email protected]\"\n}",
        "isBase64Encoded": false
    },
    "context": {
        "callbackWaitsForEmptyEventLoop": true,
        "logGroupName": "/aws/lambda/createAnIntercomHash",
        "logStreamName": "2017/06/05/[$LATEST]124241",
        "functionName": "createAnIntercomHash",
        "memoryLimitInMB": "128",
        "functionVersion": "$LATEST",
        "invokeid": "8ad3b3c0-49fe-11e7-86d5-a38a3b86ba05",
        "awsRequestId": "8ad3b3c0-49fe-11e7-86d5-a38a3b86ba05",
        "invokedFunctionArn": "arn:aws:lambda:ap-southeast-2:127579097966:function:createAnIntercomHash"
    }
}