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

cloudhopper

v2.0.1

Published

Framework for deploying your APIs with AWS Lambda by VdoCipher

Downloads

6

Readme

CloudHopper

Update 2017-01-04 : I have now updated this repo to use the API-G proxy integration. The main reason for going for 'emulating express' instead of 'bundling express' is to not to further extend the cold-start time. Starting a new express instance is a time-taking process. This affects everytime the number of concurrent invocations is increased. Also, the bundling up of all required modules seemed like a good idea. There are many use-cases when aws-serverless-express is a better idea then using cloudhopper, but I shall stick with this for now.

Update 2016-11-09 : AWS Lambda has now a better method of Proxy Integration with API Gateway. As such, this repo is now depraced. I am working on updating it to make better use of latest features in Lambda and API-G.

Join the chat at https://gitter.im/VdoCipher/cloudhopper Build Status Coverage Status

Deploy your APIs with AWS Lambda

Why CloudHopper?

  • No vendor lock-in Project can also be deployed as a normal express application.
  • Fast startup time With a single function for all end-points, the API is less affected by cold-start latency.
  • No intrusive persmissions The project is designed to just do the work of an application. It requires a finite set of IAM persmissions for setup. This also means you need to do some configuration on AWS for this to work
  • Local testing Local testing before deploying to production
  • Small deployment package The deploy tool tries to create a smaller deployment package by only including the required files
  • ExpressJS APIs The request response in lambda emulates the ExpressJS API which makes it very easy to scaffold your API

Requirements

  • NodeJS: 4.3 or greater

Getting started

Step 1: NPM init your package and add a index.js

mkdir myapp
cd myapp
touch index.js
npm init
npm i -S cloudhopper
cd node_modules/cloudhopper/
npm install 
cd ../../

Step 2: Add the following scripts to your package.json

"scripts" : {
	"cloudhopper": "cloudhopper"
}

Step 3: Your index.js should look something like this:

'use strict';

let Router = require('router');
let router = Router();
let cloudhopper = require('cloudhopper')

router.get('/', (req, res) => {
	res.json({message: "Hello world"})
});
router.use((req, res) => {
	res.status(404).json({
		message: "Endpoint does not exist"
	})
});

cloudhopper.use(router)
exports.handler = cloudhopper.handler

Step 4: Make sure the IAM user in ~/.aws/credentials has the following permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "apigateway:*"
            ],
            "Resource": [
                "arn:aws:apigateway:<region>::/restapis/<api-id>/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:UpdateFunctionCode"
            ],
            "Resource": [
                "arn:aws:lambda:<region>:<account-id>:function:<function-name>"
            ]
        }
    ]
}

Step 5: Create an empty API Gateway and basic lambda function.

Step 6: Create a git-ignored file local.cloudhopper.config.json with the following:

{
	"lambda_function_name": "xxxxxx",
	"apigateway_id": "xxxxx"
	"restApiId" : "<rest api>",
	"stageName": "<stage name>",
	"apiTitle": "<name of API, this will override API name>",
	"region": "<region>",
	"lambdaName": "<name of lambda function>",
	"tempFile": "<temp file which is in ignored list>",
	"lambdaArn": "<lambda_arn>",
	"stageVariables": {
		"local": { },
		"development": { },
		"production": { }
	}
}

Run your API locally at http://127.0.0.1:3000

npm run cloudhopper -- runLocal

Step 7: Prepare the API and packages the function and deploys it on Lambda

npm run cloudhopper -- setUpAPi
npm run cloudhopper -- deploy

Architecture

External connection:

This framework bootstraps an API Gateway which will forward everything to the lambda function. The lambda function operates from your VPC with no public DNS name. This means it can not connect to anything outside of your assigned VPC.

To connect to external network or a non-VPC endpoints or another region in your account, it requires a NAT Gateway/Instance with a private subnet. cloudcraft - cloudhopper setup

Using Express API

The Request Response objects partially emulate the corresponding objects of Express Framework such that you can easily swap express instead of cloudhopper and run the project anywhere. That said there are limited response methods that can be called: json, status, end and redirect.

These should be sufficient for an API but we can always discuss these on issues.

Configuration Parameters

The api will need to connect to various aws or third party services in order to exchange data. You should have already set up a NAT instance for providing an external route to our lambda. The hostnames or the access parameters should never be hard coded in the application. It should also not be part of the version control. For this purpose, AWS provides stage variables in API Gateway. In cloudhopper you save your variables in a file stageVariables.json which looks like this :

When you deploy your code, cloudhopper copies the production component of stageVariables.json to the API Gateway stage variables. Cloudhopper sets up the Gateway to pass these variables to lambda.

Deferred procurement of variables

This workflow requires a slightly different application structure. You need to require your routes and database config files only when you have obtained the variables. For this reason, we have a setInit function. Here is a sample of what it might look like. You must write your requires inside this setInit function.

Deploy

The deploy scripts goes through your node_modules folder and tries to create a zip archive for only the required files excluding the dev dependencies.

Local testing

Simply run npm run cloudhopper -- runLocal and your API is running on 127.0.0.1:3000

Limitations

  • Only JSON I/O
  • No Cookie support

FAQ

1. Why have a single function for all API end-points?

Having a single lambda function also helps to keep redundancy at a minimum and IMO keeps the project much more organized. All endpoints often need the same kind of db models and it feels quite useless to separate them into isolated blocks of code. The traditional resource based code structure feel more familiar.

Lambda works on docker containers on AWS managed ec2 instances. If you do not call a Lambda function for sometime, the docker is destroyed. A fresh start will take extra time because a new docker will be set up with your code.

2. Why not use the API Gateway end-points instead of having parameters?

Since, we are using the same function for multiple end-points, we need to have some kind of routing logic in the function itself. This makes the Gateway kind of redundant. Also, with API Gateway, non-existent end-points are returned with a wierd "Missing Authentication Error" which can not be overridden. This may not be 404 or 415 that you wish to return to your client. It is therefore better to just use wildcards and forward everything to the client.

License

Copyright 2016 VdoCipher Media Solutions

GPL-3.0