node package manager
Stop wasting time. Easily manage code sharing in your team. Create a free org »

marchio-lambda-put

marchio-lambda-put

REST PUT to DynamoDB via Lambda

Continuous Integration Coverage Status Downloads Version License

Installation

$ npm init
$ npm install marchio-lambda-put --save

Lambda Setup

References


Steps

Create Test Role

  • Browse to: https://console.aws.amazon.com/iam/
  • Click: Roles (from the left column)
  • Click: Create new role
  • Step 1: Select role type
  • Expand Section: AWS Service Role
  • For AWS Lambda, click: Select
  • Step 2 is automatically skipped
  • Step 3: Attach policy
  • Select both AmazonDynamoDB* policies
  • Click: Next Step
  • Create a name for the role (like lambda-db-put)
  • Click: Create role

Create Lambda Function

  • Browse to: https://console.aws.amazon.com/lambda
  • Click: Create a Lambda Function
  • Select: Blank Function
  • Click: Next
  • Name: marchio-put
  • Description: Marchio service
  • Runtime: Node.js 4.3
  • Set the Role
  • Role: Choose and existing role
  • Existing role: service-role/(name of role you created earlier)
  • Click: Next
  • Click: Create Function

Setup API Gateway

  • Browse to: https://console.aws.amazon.com/apigateway
  • Click: Create API
  • Select: New API
  • API name: marchio-put
  • Description: Marchio service
  • Click: Create API
  • Click on the slash (/)
  • Drop down: Actions
  • Select: Create Resource
  • Check: Configure as proxy resource
  • (Optionally enabled CORS)
  • Click: Create Resource
  • For Integration type select: Lambda Function Proxy
  • Lambda Region: For example: us-east-1
  • Lambda Function: marchio-put
  • Click: Save
  • Add Permission to Lambda Function: OK
  • Drop down: Actions
  • Select: Deploy API
  • Define a new stage (call it "test")
  • Click: Deploy
  • Save the Invoke URL

Create DynamoDB Table

  • Browse to: https://console.aws.amazon.com/dynamodb/
  • Click: Create Table
  • Table name: mldb
  • Primary partition key: eid
  • The type should be the default (string)
  • Click: Create
  • After some churning, click the Capacity tab
  • Set the Read / Write capacity units to 1 to save money while testing
  • Click: Save

Example and Deploy

See the deployment example located in the repo under:

  • examples/deploy

It contains a deployment script and an example lambda source file.

  • Install the dependencies by running:
$ npm install

To run the script you must first make it runnable:

$ chmod +x deploy-lambda.sh

To test:

  • Deploy the API via API Gateway
  • Create an environment variable called AWS_HOST_MARCHIO_PUT which is set to the invocation url
  • Test the deployment using curl:
$ curl -i -X PUT -H "Content-Type: application/json" -d '{"email":"test@beta.com"}' $AWS_HOST_MARCHIO_PUT/test/marchio-put/110ec58a-a0f2-4ac4-8393-c866d813b8d1
  • The response should contain a 204 status code.
  • Browse the DynamoDB table to see the updated record.

Modules

marchio-lambda-put

Module

marchio-lambda-put-factory

Factory module

marchio-lambda-put

Module

marchio-lambda-put-factory

Factory module

marchio-lambda-put-factory.create(spec) ⇒ Promise

Factory method It takes one spec parameter that must be an object with named parameters

Kind: static method of marchio-lambda-put-factory
Returns: Promise - that resolves to {module:marchio-lambda-put}

Param Type Description
spec Object Named parameters object
spec.event Object Lambda event
spec.context Object Lambda context
spec.callback function Lambda callback
spec.model Object Table model
[spec.filter] function A function that takes the original record and returns a {Promise} that resolves to a filtered record

Example (Usage example)

// Lambda root file
"use strict";
 
var mlFactory = require('marcio-lambda-put'); 
 
var getRandomInt = function (min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
};
 
// Why not just demo hashing with bcrypt?
// Because bcrypt requires installing on AWS Linux before packaging
// That's beyond the scope of this example, so we fake it.
 
function fakeHash( record ) {
   // Not a real hash function - do not use in production
   return new Promise( (resolve, reject) => {
       if(!record) {
           return reject('record not defined');
       } 
       if(record.password) {
           // only update if value passed in
           // fake hashing - do not use in production
           record.password = '$' + getRandomInt(10000, 10000000);
       }
       resolve(record);
   });
}
 
exports.handler = function(event, context, callback) {
 
    var model = {
        name: 'mldb',   // must match DynamoDB table name
        partition: 'eid', // primary partition key - cannot be reserved word (like uuid)
        // sort: 'status',  // primary sort key
        // recordMustExist: false, // default is false 
        fields: {
            email:    { type: String, required: true },
            status:   { type: String, required: true, default: "NEW" },
            // Password will be (fake) hashed by filter before being saved
            password: { type: String, select: false },  // select: false, exclude from query results
        }
    };
 
    mlFactory.create({ 
        event: event, 
        context: context,
        callback: callback,
        model: model,
        filter: fakeHash
    })
    .catch(function(err) {
        callback(err);
    });
 };

Testing

To test, go to the root folder and type (sans $):

$ npm test

Repo(s)


Contributing

In lieu of a formal style guide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code.


Version History

Version 0.3.1

  • updated deploy example

Version 0.3.0

  • removed model/table name from url
  • updated deploy-build examples

Version 0.2.1

  • updated example project

Version 0.2.0

  • changed primary model property to partition
  • added support for sort key
  • added recordMustExist flag
  • new sort key tests will fail until post and get have sort supported added

Version 0.1.0

  • initial release