Deployable hello function behind api gateway
This commit is contained in:
13
dynamoClient.js
Normal file
13
dynamoClient.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const AWS = require('aws-sdk');
|
||||
|
||||
// Set the region
|
||||
AWS.config.update({region: 'us-east-2'});
|
||||
|
||||
// also set local endpoint while in development
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
AWS.config.update({endpoint: "http://localhost:8000"});
|
||||
}
|
||||
|
||||
const client = new AWS.DynamoDB.DocumentClient({});
|
||||
|
||||
module.exports = client;
|
||||
14
handlers/hello/get.js
Normal file
14
handlers/hello/get.js
Normal file
@@ -0,0 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
module.exports.hello = async (event, context) => {
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify({
|
||||
message: 'Go Serverless v1.0! Your function executed successfully!',
|
||||
input: event,
|
||||
}),
|
||||
};
|
||||
|
||||
// Use this code if you don't use the http event with the LAMBDA-PROXY integration
|
||||
// return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
|
||||
};
|
||||
20
helpers.js
Normal file
20
helpers.js
Normal file
@@ -0,0 +1,20 @@
|
||||
const customThrow = (statusCode, message) => {
|
||||
const err = new Error();
|
||||
err.statusCode = statusCode;
|
||||
err.message = message;
|
||||
throw err;
|
||||
};
|
||||
|
||||
const createResponse = (statusCode, body) => ({
|
||||
statusCode,
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin" : "*", // Required for CORS support to work
|
||||
"Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
customThrow,
|
||||
createResponse
|
||||
};
|
||||
61
services/db.js
Normal file
61
services/db.js
Normal file
@@ -0,0 +1,61 @@
|
||||
const dynamoClient = require('../dynamoClient');
|
||||
|
||||
const create = async (tableName, item) => {
|
||||
const fullItem = {...item, created_at: Date.now()};
|
||||
|
||||
await dynamoClient.put({
|
||||
TableName: tableName,
|
||||
Item: fullItem
|
||||
}).promise();
|
||||
|
||||
// put does not return saved item, just return our object
|
||||
return fullItem;
|
||||
};
|
||||
|
||||
const get = async (tableName, keyMap) => {
|
||||
const res = await dynamoClient.get({
|
||||
TableName: tableName,
|
||||
Key: keyMap
|
||||
}).promise();
|
||||
|
||||
return res && res.Item;
|
||||
};
|
||||
|
||||
const queryByID = async (tableName, idKeyName, id) => {
|
||||
// querying by id can be used when we are querying a table
|
||||
// that has a sortKey, but we don't need to use the sortKey
|
||||
const res = await dynamoClient.query({
|
||||
TableName: "gt_answers",
|
||||
KeyConditionExpression: "#id = :idValue",
|
||||
ExpressionAttributeNames: {
|
||||
"#id": idKeyName,
|
||||
},
|
||||
ExpressionAttributeValues: {
|
||||
":idValue": id,
|
||||
}
|
||||
}).promise();
|
||||
|
||||
return res && res.Items;
|
||||
};
|
||||
|
||||
const update = async (tableName, keyMap, ue, eav) => {
|
||||
const res = await dynamoClient.update({
|
||||
TableName: tableName,
|
||||
Key: keyMap,
|
||||
UpdateExpression: ue,
|
||||
ExpressionAttributeValues: eav,
|
||||
ReturnValues: 'UPDATED_NEW'
|
||||
}).promise();
|
||||
|
||||
console.log('update res', res);
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
client: dynamoClient,
|
||||
create,
|
||||
get,
|
||||
queryByID,
|
||||
update
|
||||
};
|
||||
35
validators/index.js
Normal file
35
validators/index.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const Ajv = require('ajv');
|
||||
const {customThrow} = require('../helpers');
|
||||
|
||||
const parseAndValidateBody = async (schema, body) => {
|
||||
let parsedBody;
|
||||
|
||||
try {
|
||||
parsedBody = JSON.parse(body);
|
||||
} catch (err) {
|
||||
customThrow(400, 'Error. Malformed event.parsedBody.');
|
||||
}
|
||||
|
||||
const validation = validateBody(schema, parsedBody);
|
||||
|
||||
if (!validation.isValid) {
|
||||
customThrow(400, validation.error);
|
||||
}
|
||||
|
||||
return parsedBody;
|
||||
};
|
||||
|
||||
const validateBody = (schema, body) => {
|
||||
const ajv = new Ajv();
|
||||
const validate = ajv.compile(schema);
|
||||
const isValid = validate(body);
|
||||
|
||||
return {
|
||||
isValid: isValid,
|
||||
error: JSON.stringify(validate.errors)
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
parseAndValidateBody,
|
||||
};
|
||||
33
validators/schemas.js
Normal file
33
validators/schemas.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const answerSchema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_id": {"type": "string"},
|
||||
"question_id": {"type": "string"},
|
||||
"is_correct": {"type": "boolean"}
|
||||
},
|
||||
"required": ["user_id", "question_id", "is_correct"]
|
||||
};
|
||||
|
||||
const userSchema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "string"},
|
||||
"score": {"type": "number"}
|
||||
},
|
||||
"required": ["user_id", "question_id", "is_correct"]
|
||||
};
|
||||
|
||||
const loginFollowUpSchema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"accessToken": {"type": "string"}
|
||||
},
|
||||
"required": ["accessToken"]
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
answerSchema,
|
||||
userSchema,
|
||||
loginFollowUpSchema
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user