Skip to content

Instantly share code, notes, and snippets.

@rcdelacruz
Last active May 15, 2017 07:28
Show Gist options
  • Save rcdelacruz/e31f8b6dd32fadcf6a72d2684f25f069 to your computer and use it in GitHub Desktop.
Save rcdelacruz/e31f8b6dd32fadcf6a72d2684f25f069 to your computer and use it in GitHub Desktop.
import uuid from 'uuid';
import * as dynamoDbLib from '../../libs/dynamodb-lib';
import {
success,
failure
} from '../../libs/response-lib';
const collectionHandlers = {
"GET": listItems,
"POST": createItem,
}
const itemHandlers = {
"DELETE": deleteItem,
"GET": getItem,
//"PATCH": patchItem,
//"POST": postItem,
"PUT": updateItem,
}
export async function main(event, context, callback) {
let id = (event["pathParameters"] !== null && "id" in event["pathParameters"]) ? event["pathParameters"]["id"] : undefined;
let handlers = (id === undefined) ? collectionHandlers : itemHandlers;
let httpMethod = event["httpMethod"];
if (httpMethod in handlers) {
return handlers[httpMethod](event, context, callback);
}
}
async function deleteItem(event, context, callback) {
const params = {
TableName: 'notes',
// 'Key' defines the partition key and sort key of the time to be removed
// - 'userId': User Pool sub of the authenticated user
// - 'noteId': path parameter
Key: {
userId: event.requestContext.authorizer.claims.sub,
noteId: event.pathParameters.id,
},
};
try {
const result = await dynamoDbLib.call('delete', params);
callback(null, success({
status: true
}));
} catch (e) {
callback(null, failure({
status: false
}));
}
}
async function listItems(event, context, callback) {
//console.log(event);
const params = {
TableName: 'notes',
// 'KeyConditionExpression' defines the condition for the query
// - 'userId = :userId': only return items with matching 'userId' partition key
// 'ExpressionAttributeValues' defines the value in the condition
// - ':userId': defines 'userId' to be User Pool sub of the authenticated user
KeyConditionExpression: "userId = :userId",
ExpressionAttributeValues: {
":userId": event.requestContext.authorizer.claims.sub,
}
};
try {
const result = await dynamoDbLib.call('query', params);
// Return the matching list of items in response body
callback(null, success(result.Items));
} catch (e) {
callback(null, failure({
status: false
}));
}
};
async function getItem(event, context, callback) {
const params = {
TableName: 'notes',
// 'Key' defines the partition key and sort key of the time to be retrieved
// - 'userId': federated identity ID of the authenticated user
// - 'noteId': path parameter
Key: {
userId: event.requestContext.authorizer.claims.sub,
noteId: event.pathParameters.id,
},
};
try {
const result = await dynamoDbLib.call('get', params);
if (result.Item) {
// Return the retrieved item
callback(null, success(result.Item));
} else {
callback(null, failure({
status: false,
error: 'Item not found.'
}));
}
} catch (e) {
callback(null, failure({
status: false
}));
}
}
async function createItem(event, context, callback) {
const data = JSON.parse(event.body);
const params = {
TableName: 'notes',
Item: {
userId: event.requestContext.authorizer.claims.sub,
noteId: uuid.v1(),
content: data.content,
attachment: data.attachment,
createdAt: new Date().getTime(),
},
};
try {
const result = await dynamoDbLib.call('put', params);
callback(null, success(params.Item));
} catch (e) {
callback(null, failure({
status: false
}));
}
}
async function updateItem(event, context, callback) {
const data = JSON.parse(event.body);
const params = {
TableName: 'notes',
// 'Key' defines the partition key and sort key of the time to be updated
// - 'userId': User Pool sub of the authenticated user
// - 'noteId': path parameter
Key: {
userId: event.requestContext.authorizer.claims.sub,
noteId: event.pathParameters.id,
},
// 'UpdateExpression' defines the attributes to be updated
// 'ExpressionAttributeValues' defines the value in the update expression
UpdateExpression: 'SET content = :content, attachment = :attachment',
ExpressionAttributeValues: {
':attachment': data.attachment ? data.attachment : null,
':content': data.content ? data.content : null,
},
ReturnValues: 'ALL_NEW',
};
try {
const result = await dynamoDbLib.call('update', params);
callback(null, success({
status: true
}));
} catch (e) {
callback(null, failure({
status: false
}));
}
}
export function success(body) {
return buildResponse(200, body);
}
export function failure(body) {
return buildResponse(500, body);
}
function buildResponse(statusCode, body) {
return {
statusCode: statusCode,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true,
},
body: JSON.stringify(body),
};
}
service: notes-app-api-new
plugins:
- serverless-webpack
custom:
webpackIncludeModules: true
provider:
name: aws
runtime: nodejs6.10
stage: prod
region: ap-southeast-1
memorySize: 128
# 'iamRoleStatement' defines the permission policy for the Lambda function.
# In this case Lambda functions are granted with permissions to access DynamoDB.
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:ap-southeast-1:*:*"
functions:
# Defines an HTTP API endpoint that calls the main function in create.js
# - path: url path is /notes
# - method: POST request
# - cors: enabled CORS (Cross-Origin Resource Sharing) for browser cross
# domain api call
# - authorizer: authenticate the api via Cognito User Pool. Update the 'arn'
# with your own User Pool ARN
notes:
handler: handler.main
events:
- http:
path: v1/notes
method: any
cors: true
authorizer:
arn: arn:aws:cognito-idp:ap-northeast-1:3099xxx:userpool/ap-northeast-1_t4IJ4oPKl
- http:
path: v1/notes/{id}
method: any
cors: true
authorizer:
arn: arn:aws:cognito-idp:ap-northeast-1:3099xxx:userpool/ap-northeast-1_t4IJ4oPKl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment