diff --git a/README.md b/README.md index eb27f53..58be004 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,4 @@ Each example contains a README.md with an explanation about the solution and it' | [`kmeans-sklearn`](kmeans-sklearn)
Simple kmeans examples using sklearn | python2 | | [`naive-serverless-map-reduce`](naive-serverless-map-reduce)
Naive serverless MapReduce | nodeJS | | [`typescript-function`](typescript-function)
Boilerplate TypeScript Binaris function | nodeJS and TypeScript | +| [`nodejs-crud-dynamo`](nodejs-crud-dynamo)
Basic CRUD example using DynamoDB | nodeJS | diff --git a/nodejs-crud-dynamo/README.md b/nodejs-crud-dynamo/README.md new file mode 100644 index 0000000..0db2b9f --- /dev/null +++ b/nodejs-crud-dynamo/README.md @@ -0,0 +1,84 @@ +# NodeJS DynamoDB CRUD + +Wraps basic CRUD operations for DynamoDB in Binaris functions. + +# Using the CRUD + +It is assumed you already have a Binaris account. If you don't have an account yet, worry not, signing up is painless and takes just 2 minutes. Visit [Getting Started](https://dev.binaris.com/tutorials/nodejs/getting-started/) to find concise instructions for the process. + +To use any of the functions in this example, you must export the following three variables into your environment (before deployment). + +* `AWS_ACCESS_KEY_ID` # AWS access key +* `AWS_SECRET_ACCESS_KEY` # secret AWS credential +* `AWS_REGION` # AWS region used for DynamoDB + +## Deploy + +A helper command "deploy" is defined in the package.json to simplify the deployment process + +```bash +$ npm run deploy +``` + +## Create the Table + +```bash +$ bn invoke createDriversTable +``` + +## Create a Driver + +```bash +$ npm run createDriver +``` + +or + +```bash +$ bn invoke createDriver --json ./queries/createDriver.json +``` + +## Read a Driver + +```bash +$ npm run readDriver +``` + +or + +```bash +$ bn invoke readDriver --json ./queries/readDriver.json +``` + +## Update a Driver + +```bash +$ npm run updateDriver +``` + +or + +```bash +$ bn invoke updateDriver --json ./queries/updateDriver.json +``` + +## Delete a Driver + +```bash +$ npm run deleteDriver +``` + +or + +```bash +$ bn invoke deleteDriver --json ./queries/deleteDriver.json +``` + + +## Remove + +A helper command "remove" is defined in the package.json to simplify the removal process + +```bash +$ npm run remove +``` \ No newline at end of file diff --git a/nodejs-crud-dynamo/binaris.yml b/nodejs-crud-dynamo/binaris.yml new file mode 100644 index 0000000..8591f74 --- /dev/null +++ b/nodejs-crud-dynamo/binaris.yml @@ -0,0 +1,46 @@ +functions: + createDriversTable: + file: function.js + entrypoint: createDriversTable + executionModel: concurrent + runtime: node8 + env: + AWS_ACCESS_KEY_ID: + AWS_SECRET_ACCESS_KEY: + AWS_REGION: + createDriver: + file: function.js + entrypoint: createDriver + executionModel: concurrent + runtime: node8 + env: + AWS_ACCESS_KEY_ID: + AWS_SECRET_ACCESS_KEY: + AWS_REGION: + readDriver: + file: function.js + entrypoint: readDriver + executionModel: concurrent + runtime: node8 + env: + AWS_ACCESS_KEY_ID: + AWS_SECRET_ACCESS_KEY: + AWS_REGION: + updateDriver: + file: function.js + entrypoint: updateDriver + executionModel: concurrent + runtime: node8 + env: + AWS_ACCESS_KEY_ID: + AWS_SECRET_ACCESS_KEY: + AWS_REGION: + deleteDriver: + file: function.js + entrypoint: deleteDriver + executionModel: concurrent + runtime: node8 + env: + AWS_ACCESS_KEY_ID: + AWS_SECRET_ACCESS_KEY: + AWS_REGION: diff --git a/nodejs-crud-dynamo/deploy.sh b/nodejs-crud-dynamo/deploy.sh new file mode 100755 index 0000000..6da9bd2 --- /dev/null +++ b/nodejs-crud-dynamo/deploy.sh @@ -0,0 +1,6 @@ +#!/bin/bash +functions=( createDriversTable createDriver readDriver updateDriver deleteDriver ) +for i in "${functions[@]}" +do + bn deploy $i +done diff --git a/nodejs-crud-dynamo/function.js b/nodejs-crud-dynamo/function.js new file mode 100644 index 0000000..015fdf4 --- /dev/null +++ b/nodejs-crud-dynamo/function.js @@ -0,0 +1,100 @@ +const AWS = require('aws-sdk'); + +const { + AWS_ACCESS_KEY_ID, + AWS_SECRET_ACCESS_KEY, + AWS_REGION +} = process.env; + +AWS.config.update({ + accessKeyId: AWS_ACCESS_KEY_ID, + secretAccessKey: AWS_SECRET_ACCESS_KEY, + region: AWS_REGION, + endpoint: `https://dynamodb.${AWS_REGION}.amazonaws.com`, +}); + +const dynamoDB = new AWS.DynamoDB(); +const docClient = new AWS.DynamoDB.DocumentClient(); + +function validatedBody(body, ...fields) { + for (const field of fields) { + if (!Object.prototype.hasOwnProperty.call(body, field)) { + throw new Error(`Missing request body parameter: ${field}.`); + } + } + return body; +} + +const TableName = 'Drivers'; +const PrimaryKey = 'driverID'; + +exports.createDriversTable = async () => { + return dynamoDB.createTable({ + TableName, + KeySchema: [{ + AttributeName: PrimaryKey, + KeyType: 'HASH', + }], + AttributeDefinitions: [{ + AttributeName: PrimaryKey, + AttributeType: 'S', + }], + ProvisionedThroughput: { + ReadCapacityUnits: 10, + WriteCapacityUnits: 10, + } + }).promise(); +}; + +exports.createDriver = async (body) => { + const { + driverID, + rideStatus, + lastLocation + } = validatedBody(body, 'driverID', 'rideStatus', 'lastLocation'); + + return docClient.put({ + TableName, + Item: { + driverID, + rideStatus, + lastLocation, + } + }).promise(); +}; + +exports.readDriver = async (body) => { + const { driverID } = validatedBody(body, 'driverID'); + return docClient.get({ TableName, Key: { driverID } }).promise(); +}; + +exports.updateDriver = async (body) => { + const { + driverID, + rideStatus, + lastLocation + } = validatedBody(body, 'driverID', 'rideStatus', 'lastLocation'); + + return docClient.update({ + TableName, + Key: { driverID }, + UpdateExpression: 'SET #loc.#lon = :lonVal, #loc.#lat = :latVal, #rideStatus= :r', + ExpressionAttributeNames: { + '#loc': 'lastLocation', + '#lon': 'longitude', + '#lat': 'latitude', + '#rideStatus': 'rideStatus', + }, + ExpressionAttributeValues: { + ':r': rideStatus, + ':lonVal': lastLocation.longitude, + ':latVal': lastLocation.latitude, + }, + ReturnValues: 'UPDATED_NEW' + }).promise(); +}; + +exports.deleteDriver = async (body) => { + const { driverID } = validatedBody(body, 'driverID'); + return docClient.delete({ TableName, Key: { driverID } }).promise(); +}; diff --git a/nodejs-crud-dynamo/package.json b/nodejs-crud-dynamo/package.json new file mode 100644 index 0000000..93301b4 --- /dev/null +++ b/nodejs-crud-dynamo/package.json @@ -0,0 +1,34 @@ +{ + "name": "nodejs-crud-dynamo", + "version": "1.0.0", + "private": true, + "license": "MIT", + "description": "An example CRUD around DynamoDB", + "main": "function.js", + "repository": { + "type": "git", + "url": "git+https://github.com/binaris/functions-examples.git" + }, + "scripts": { + "deploy": "./deploy", + "remove": "./remove", + "createDriver": "bn invoke createDriver --json ./queries/createDriver.json", + "readDriver": "bn invoke readDriver --json ./queries/readDriver.json", + "updateDriver": "bn invoke updateDriver --json ./queries/updateDriver.json", + "deleteDriver": "bn invoke deleteDriver --json ./queries/deleteDriver.json" + }, + "bugs": { + "url": "https://github.com/binaris/functions-examples/issues" + }, + "homepage": "https://github.com/binaris/functions-examples/nodejs-crud-dynamo/README.md", + "author": "Ryland Goldstein", + "dependencies": { + "aws-sdk": "^2.430.0" + }, + "keywords": [ + "Binaris", + "FaaS", + "CRUD", + "DynamoDB" + ] +} diff --git a/nodejs-crud-dynamo/queries/createDriver.json b/nodejs-crud-dynamo/queries/createDriver.json new file mode 100644 index 0000000..6118cd5 --- /dev/null +++ b/nodejs-crud-dynamo/queries/createDriver.json @@ -0,0 +1,8 @@ +{ + "driverID": "a21s312qew313hdg", + "rideStatus": "HAS_RIDER", + "lastLocation": { + "longitude": "-77.0364", + "latitude": "38.8951" + } +} diff --git a/nodejs-crud-dynamo/queries/deleteDriver.json b/nodejs-crud-dynamo/queries/deleteDriver.json new file mode 100644 index 0000000..79f2816 --- /dev/null +++ b/nodejs-crud-dynamo/queries/deleteDriver.json @@ -0,0 +1,3 @@ +{ + "driverID": "a21s312qew313hdg" +} diff --git a/nodejs-crud-dynamo/queries/readDriver.json b/nodejs-crud-dynamo/queries/readDriver.json new file mode 100644 index 0000000..79f2816 --- /dev/null +++ b/nodejs-crud-dynamo/queries/readDriver.json @@ -0,0 +1,3 @@ +{ + "driverID": "a21s312qew313hdg" +} diff --git a/nodejs-crud-dynamo/queries/updateDriver.json b/nodejs-crud-dynamo/queries/updateDriver.json new file mode 100644 index 0000000..2f2459d --- /dev/null +++ b/nodejs-crud-dynamo/queries/updateDriver.json @@ -0,0 +1,8 @@ +{ + "driverID": "a21s312qew313hdg", + "rideStatus": "NO_RIDER", + "lastLocation": { + "longitude": "-78.0364", + "latitude": "38.8851" + } +} diff --git a/nodejs-crud-dynamo/remove.sh b/nodejs-crud-dynamo/remove.sh new file mode 100755 index 0000000..cb5f89c --- /dev/null +++ b/nodejs-crud-dynamo/remove.sh @@ -0,0 +1,6 @@ +#!/bin/bash +functions=( createDriversTable createDriver readDriver updateDriver deleteDriver ) +for i in "${functions[@]}" +do + bn remove $i +done