├── .gitignore ├── README.md ├── databaseManager.js ├── index.js ├── package-lock.json ├── package.json ├── package.yml └── template.yml /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | packaged-template.yamls -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | This git repository is an example microservice to perform CRUD operation. This microservice is deployed on AWS Lamnda and API Gateway using SAM(Serverless application model). SAM cli is a great tool to manage your AWS infrastructure and achieve IaC(Infrastructure as Code) model. 3 | 4 | # Prerequisite 5 | - Knowledge of NodeJs, Basic Javascript and api development 6 | - Understanding of AWS services 7 | - AWS CLI installed and configured 8 | - SAM CLI installed and configured 9 | - NodeJs 8.10 or greater installed on local machine 10 | 11 | # Highlights 12 | - Use of SAM Templates to create infra and deploy code 13 | - Create a serverless lambda function in NodeJs 14 | - Store data in dynamoDB using NodeJs and lambda function 15 | - Use of API Gateway AWS service to trigger lambda function 16 | 17 | # Commands 18 | Once you clone the repository or create your own function and template following commands are required to package and deploy the application. 19 | - Packaging - sam package --template-file template.yml --output-template-file package.yml --s3-bucket YOUR_BUCKET_NAME 20 | - Deploying - sam deploy --template-file package.yml --stack-name YOUR_STACK_NAME --capabilities CAPABILITY_IAM 21 | 22 | For example: 23 | 24 | - Packaging - sam package --template-file template.yml --output-template-file package.yml --s3-bucket inkloft-backend-products 25 | - Deploying - sam deploy --template-file package.yml --stack-name inkloft-backend-products --capabilities CAPABILITY_IAM -------------------------------------------------------------------------------- /databaseManager.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const AWS = require('aws-sdk'); 4 | let dynamo = new AWS.DynamoDB.DocumentClient(); 5 | 6 | const TABLE_NAME = 'inkProductsTable'; 7 | 8 | module.exports.initializateDynamoClient = newDynamo => { 9 | dynamo = newDynamo; 10 | }; 11 | 12 | module.exports.saveItem = item => { 13 | const params = { 14 | TableName: TABLE_NAME, 15 | Item: item 16 | }; 17 | 18 | return dynamo 19 | .put(params) 20 | .promise() 21 | .then((result) => { 22 | return item; 23 | }, (error) => { 24 | return error; 25 | }); 26 | }; 27 | 28 | module.exports.getItem = itemId => { 29 | const params = { 30 | Key: { 31 | productId: itemId 32 | }, 33 | TableName: TABLE_NAME 34 | }; 35 | 36 | return dynamo 37 | .get(params) 38 | .promise() 39 | .then((result) => { 40 | return result.Item; 41 | }, (error) => { 42 | return error; 43 | }); 44 | }; 45 | 46 | module.exports.deleteItem = itemId => { 47 | const params = { 48 | Key: { 49 | productId: itemId 50 | }, 51 | TableName: TABLE_NAME 52 | }; 53 | 54 | return dynamo.delete(params).promise(); 55 | }; 56 | 57 | module.exports.updateItem = (itemId, item) => { 58 | 59 | let vbl = "x"; 60 | let adder = "y"; 61 | let updateexp = 'set '; 62 | let itemKeys = Object.keys(item); 63 | let expattvalues = {}; 64 | 65 | for (let i = 0; i < itemKeys.length; i++) { 66 | vbl = vbl+adder; 67 | 68 | if((itemKeys.length-1)==i) 69 | updateexp += itemKeys[i] + ' = :'+ vbl; 70 | else 71 | updateexp += itemKeys[i] + ' = :'+ vbl + ", "; 72 | 73 | expattvalues[":"+vbl] = item[itemKeys[i]]; 74 | } 75 | 76 | console.log("update expression and expressionAttributeValues"); 77 | console.log(updateexp, expattvalues); 78 | 79 | const params = { 80 | TableName: TABLE_NAME, 81 | Key: { 82 | productId: itemId 83 | }, 84 | ConditionExpression: 'attribute_exists(productId)', 85 | UpdateExpression: updateexp, 86 | ExpressionAttributeValues: expattvalues, 87 | ReturnValues: 'ALL_NEW' 88 | }; 89 | 90 | return dynamo 91 | .update(params) 92 | .promise() 93 | .then(response => { 94 | return response.Attributes; 95 | }, (error) => { 96 | return error; 97 | }); 98 | }; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const databaseManager = require('./databaseManager'); 4 | const uuidv1 = require('uuid/v1'); 5 | 6 | exports.productHandler = function(event, context, callback){ 7 | 8 | console.log(event, context); 9 | 10 | switch (event.httpMethod) { 11 | case 'DELETE': 12 | deleteItem(event, callback); 13 | break; 14 | case 'GET': 15 | getItem(event, callback); 16 | break; 17 | case 'POST': 18 | saveItem(event, callback); 19 | break; 20 | case 'PUT': 21 | updateItem(event, callback); 22 | break; 23 | default: 24 | sendResponse(404, `Unsupported method "${event.httpMethod}"`, callback); 25 | } 26 | }; 27 | 28 | function saveItem(event, callback) { 29 | const item = JSON.parse(event.body); 30 | 31 | item.productId = uuidv1(); 32 | 33 | databaseManager.saveItem(item).then(response => { 34 | console.log(response); 35 | sendResponse(200, item.productId, callback); 36 | }, (reject) =>{ 37 | sendResponse(400, reject, callback); 38 | }); 39 | } 40 | 41 | function getItem(event, callback) { 42 | const itemId = event.pathParameters.productId; 43 | 44 | databaseManager.getItem(itemId).then(response => { 45 | console.log(response); 46 | if(response) 47 | sendResponse(200, response, callback); 48 | else 49 | sendResponse(404, "Please passa valid productId", callback); 50 | 51 | },(reject) =>{ 52 | sendResponse(400, reject, callback); 53 | }); 54 | } 55 | 56 | function deleteItem(event, callback) { 57 | const itemId = event.pathParameters.productId; 58 | 59 | databaseManager.deleteItem(itemId).then(response => { 60 | sendResponse(200, 'DELETE ITEM', callback); 61 | }, (reject) => { 62 | sendResponse(400, reject, callback); 63 | }); 64 | } 65 | 66 | function updateItem(event, callback) { 67 | const itemId = event.pathParameters.productId; 68 | 69 | const body = JSON.parse(event.body); 70 | 71 | databaseManager.updateItem(itemId, body).then(response => { 72 | console.log(response); 73 | sendResponse(200, response, callback); 74 | }, (reject) => { 75 | sendResponse(400, reject, callback); 76 | }); 77 | } 78 | 79 | function sendResponse(statusCode, message, callback) { 80 | const response = { 81 | statusCode: statusCode, 82 | body: JSON.stringify(message) 83 | }; 84 | callback(null, response); 85 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "inkloft-backend", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "any-promise": { 8 | "version": "1.3.0", 9 | "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", 10 | "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" 11 | }, 12 | "async": { 13 | "version": "1.5.2", 14 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 15 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" 16 | }, 17 | "aws-sdk": { 18 | "version": "2.392.0", 19 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.392.0.tgz", 20 | "integrity": "sha512-mwIJj0u8XGXepJJ66kFG6uXrZOrcPauESoHAHZfr28i2qRAnemM4B3FlWleHy6Y8pxfW6UBe2++/j2+Q+LuJhg==", 21 | "requires": { 22 | "buffer": "4.9.1", 23 | "events": "1.1.1", 24 | "ieee754": "1.1.8", 25 | "jmespath": "0.15.0", 26 | "querystring": "0.2.0", 27 | "sax": "1.2.1", 28 | "url": "0.10.3", 29 | "uuid": "3.3.2", 30 | "xml2js": "0.4.19" 31 | }, 32 | "dependencies": { 33 | "uuid": { 34 | "version": "3.3.2", 35 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 36 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" 37 | } 38 | } 39 | }, 40 | "balanced-match": { 41 | "version": "1.0.0", 42 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 43 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 44 | "optional": true 45 | }, 46 | "base64-js": { 47 | "version": "1.3.0", 48 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", 49 | "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" 50 | }, 51 | "brace-expansion": { 52 | "version": "1.1.11", 53 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 54 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 55 | "optional": true, 56 | "requires": { 57 | "balanced-match": "^1.0.0", 58 | "concat-map": "0.0.1" 59 | } 60 | }, 61 | "buffer": { 62 | "version": "4.9.1", 63 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", 64 | "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", 65 | "requires": { 66 | "base64-js": "^1.0.2", 67 | "ieee754": "^1.1.4", 68 | "isarray": "^1.0.0" 69 | } 70 | }, 71 | "bunyan": { 72 | "version": "1.5.1", 73 | "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.5.1.tgz", 74 | "integrity": "sha1-X259RMQ7lS9WsPQTCeOrEjkbTi0=", 75 | "requires": { 76 | "dtrace-provider": "~0.6", 77 | "mv": "~2", 78 | "safe-json-stringify": "~1" 79 | } 80 | }, 81 | "concat-map": { 82 | "version": "0.0.1", 83 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 84 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 85 | "optional": true 86 | }, 87 | "dtrace-provider": { 88 | "version": "0.6.0", 89 | "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", 90 | "integrity": "sha1-CweNVReTfYcxAUUtkUZzdVe3XlE=", 91 | "optional": true, 92 | "requires": { 93 | "nan": "^2.0.8" 94 | } 95 | }, 96 | "dynamodb": { 97 | "version": "1.2.0", 98 | "resolved": "https://registry.npmjs.org/dynamodb/-/dynamodb-1.2.0.tgz", 99 | "integrity": "sha512-O28acIHevSLRL7GOzX2oKgPD2tQnzjJsy92L27hjUGUXz+ETgLRTVw5lOujIIpLJBncDNJlx1KN1qfBwp2AmMw==", 100 | "requires": { 101 | "async": "1.5.x", 102 | "aws-sdk": "^2.186.x", 103 | "bunyan": "1.5.x", 104 | "joi": "10.6.x", 105 | "lodash": "4.x.x", 106 | "node-uuid": "1.4.x", 107 | "stream-to-promise": "~2.2.0" 108 | } 109 | }, 110 | "end-of-stream": { 111 | "version": "1.1.0", 112 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", 113 | "integrity": "sha1-6TUyWLqpEIll78QcsO+K3i88+wc=", 114 | "requires": { 115 | "once": "~1.3.0" 116 | }, 117 | "dependencies": { 118 | "once": { 119 | "version": "1.3.3", 120 | "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", 121 | "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", 122 | "requires": { 123 | "wrappy": "1" 124 | } 125 | } 126 | } 127 | }, 128 | "events": { 129 | "version": "1.1.1", 130 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", 131 | "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" 132 | }, 133 | "glob": { 134 | "version": "6.0.4", 135 | "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", 136 | "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", 137 | "optional": true, 138 | "requires": { 139 | "inflight": "^1.0.4", 140 | "inherits": "2", 141 | "minimatch": "2 || 3", 142 | "once": "^1.3.0", 143 | "path-is-absolute": "^1.0.0" 144 | } 145 | }, 146 | "hoek": { 147 | "version": "4.2.1", 148 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", 149 | "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" 150 | }, 151 | "ieee754": { 152 | "version": "1.1.8", 153 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", 154 | "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" 155 | }, 156 | "inflight": { 157 | "version": "1.0.6", 158 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 159 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 160 | "optional": true, 161 | "requires": { 162 | "once": "^1.3.0", 163 | "wrappy": "1" 164 | } 165 | }, 166 | "inherits": { 167 | "version": "2.0.3", 168 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 169 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 170 | "optional": true 171 | }, 172 | "isarray": { 173 | "version": "1.0.0", 174 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 175 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 176 | }, 177 | "isemail": { 178 | "version": "2.2.1", 179 | "resolved": "https://registry.npmjs.org/isemail/-/isemail-2.2.1.tgz", 180 | "integrity": "sha1-A1PT2aYpUQgMJiwqoKQrjqjp4qY=" 181 | }, 182 | "items": { 183 | "version": "2.1.2", 184 | "resolved": "https://registry.npmjs.org/items/-/items-2.1.2.tgz", 185 | "integrity": "sha512-kezcEqgB97BGeZZYtX/MA8AG410ptURstvnz5RAgyFZ8wQFPMxHY8GpTq+/ZHKT3frSlIthUq7EvLt9xn3TvXg==" 186 | }, 187 | "jmespath": { 188 | "version": "0.15.0", 189 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", 190 | "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" 191 | }, 192 | "joi": { 193 | "version": "10.6.0", 194 | "resolved": "https://registry.npmjs.org/joi/-/joi-10.6.0.tgz", 195 | "integrity": "sha512-hBF3LcqyAid+9X/pwg+eXjD2QBZI5eXnBFJYaAkH4SK3mp9QSRiiQnDYlmlz5pccMvnLcJRS4whhDOTCkmsAdQ==", 196 | "requires": { 197 | "hoek": "4.x.x", 198 | "isemail": "2.x.x", 199 | "items": "2.x.x", 200 | "topo": "2.x.x" 201 | } 202 | }, 203 | "lodash": { 204 | "version": "4.17.11", 205 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", 206 | "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" 207 | }, 208 | "minimatch": { 209 | "version": "3.0.4", 210 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 211 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 212 | "optional": true, 213 | "requires": { 214 | "brace-expansion": "^1.1.7" 215 | } 216 | }, 217 | "minimist": { 218 | "version": "0.0.8", 219 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 220 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 221 | "optional": true 222 | }, 223 | "mkdirp": { 224 | "version": "0.5.1", 225 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 226 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 227 | "optional": true, 228 | "requires": { 229 | "minimist": "0.0.8" 230 | } 231 | }, 232 | "mv": { 233 | "version": "2.1.1", 234 | "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", 235 | "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", 236 | "optional": true, 237 | "requires": { 238 | "mkdirp": "~0.5.1", 239 | "ncp": "~2.0.0", 240 | "rimraf": "~2.4.0" 241 | } 242 | }, 243 | "nan": { 244 | "version": "2.12.1", 245 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", 246 | "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", 247 | "optional": true 248 | }, 249 | "ncp": { 250 | "version": "2.0.0", 251 | "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", 252 | "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", 253 | "optional": true 254 | }, 255 | "node-uuid": { 256 | "version": "1.4.8", 257 | "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", 258 | "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" 259 | }, 260 | "once": { 261 | "version": "1.4.0", 262 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 263 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 264 | "requires": { 265 | "wrappy": "1" 266 | } 267 | }, 268 | "path-is-absolute": { 269 | "version": "1.0.1", 270 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 271 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 272 | "optional": true 273 | }, 274 | "punycode": { 275 | "version": "1.3.2", 276 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 277 | "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" 278 | }, 279 | "querystring": { 280 | "version": "0.2.0", 281 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 282 | "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" 283 | }, 284 | "rimraf": { 285 | "version": "2.4.5", 286 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", 287 | "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", 288 | "optional": true, 289 | "requires": { 290 | "glob": "^6.0.1" 291 | } 292 | }, 293 | "safe-json-stringify": { 294 | "version": "1.2.0", 295 | "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", 296 | "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", 297 | "optional": true 298 | }, 299 | "sax": { 300 | "version": "1.2.1", 301 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", 302 | "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" 303 | }, 304 | "stream-to-array": { 305 | "version": "2.3.0", 306 | "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", 307 | "integrity": "sha1-u/azn19D7DC8cbq8s3VXrOzzQ1M=", 308 | "requires": { 309 | "any-promise": "^1.1.0" 310 | } 311 | }, 312 | "stream-to-promise": { 313 | "version": "2.2.0", 314 | "resolved": "https://registry.npmjs.org/stream-to-promise/-/stream-to-promise-2.2.0.tgz", 315 | "integrity": "sha1-se2y4cjLESidG1A8CNPyrvUeZQ8=", 316 | "requires": { 317 | "any-promise": "~1.3.0", 318 | "end-of-stream": "~1.1.0", 319 | "stream-to-array": "~2.3.0" 320 | } 321 | }, 322 | "topo": { 323 | "version": "2.0.2", 324 | "resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz", 325 | "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=", 326 | "requires": { 327 | "hoek": "4.x.x" 328 | } 329 | }, 330 | "url": { 331 | "version": "0.10.3", 332 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", 333 | "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", 334 | "requires": { 335 | "punycode": "1.3.2", 336 | "querystring": "0.2.0" 337 | } 338 | }, 339 | "wrappy": { 340 | "version": "1.0.2", 341 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 342 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 343 | }, 344 | "xml2js": { 345 | "version": "0.4.19", 346 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", 347 | "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", 348 | "requires": { 349 | "sax": ">=0.6.0", 350 | "xmlbuilder": "~9.0.1" 351 | } 352 | }, 353 | "xmlbuilder": { 354 | "version": "9.0.7", 355 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", 356 | "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" 357 | } 358 | } 359 | } 360 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "inkloft-backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /package.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Resources: 3 | ProductCRUDFunction: 4 | Properties: 5 | CodeUri: s3://inkloft-backend-products/bebde7b3aa848f4f0a879ed268ecbc78 6 | Events: 7 | ProductGetAPI: 8 | Properties: 9 | Method: ANY 10 | Path: /product/{productId} 11 | Type: Api 12 | ProductPostAPI: 13 | Properties: 14 | Method: POST 15 | Path: /product 16 | Type: Api 17 | Handler: index.productHandler 18 | Policies: 19 | - Statement: 20 | - Action: 21 | - dynamodb:DeleteItem 22 | - dynamodb:GetItem 23 | - dynamodb:PutItem 24 | - dynamodb:UpdateItem 25 | Effect: Allow 26 | Resource: 27 | Fn::Join: 28 | - '' 29 | - - 'arn:aws:dynamodb:' 30 | - Ref: AWS::Region 31 | - ':' 32 | - Ref: AWS::AccountId 33 | - :table/inkProductsTable 34 | Version: '2012-10-17' 35 | Runtime: nodejs8.10 36 | Type: AWS::Serverless::Function 37 | inkProductsTable: 38 | Properties: 39 | AttributeDefinitions: 40 | - AttributeName: productId 41 | AttributeType: S 42 | KeySchema: 43 | - AttributeName: productId 44 | KeyType: HASH 45 | ProvisionedThroughput: 46 | ReadCapacityUnits: 5 47 | WriteCapacityUnits: 5 48 | TableName: inkProductsTable 49 | Type: AWS::DynamoDB::Table 50 | Transform: AWS::Serverless-2016-10-31 51 | -------------------------------------------------------------------------------- /template.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion : '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Resources: 4 | ProductCRUDFunction: 5 | Type: AWS::Serverless::Function 6 | Properties: 7 | Handler: index.productHandler 8 | Runtime: nodejs8.10 9 | Events: 10 | ProductPostAPI: 11 | Type: Api 12 | Properties: 13 | Path: /product 14 | Method: POST 15 | ProductGetAPI: 16 | Type: Api 17 | Properties: 18 | Path: /product/{productId} 19 | Method: ANY 20 | 21 | Policies: 22 | - Version: '2012-10-17' 23 | Statement: 24 | - Effect: Allow 25 | Action: 26 | - 'dynamodb:DeleteItem' 27 | - 'dynamodb:GetItem' 28 | - 'dynamodb:PutItem' 29 | - 'dynamodb:UpdateItem' 30 | Resource: 31 | 'Fn::Join': 32 | - '' 33 | - - 'arn:aws:dynamodb:' 34 | - Ref: 'AWS::Region' 35 | - ':' 36 | - Ref: 'AWS::AccountId' 37 | - ':table/inkProductsTable' 38 | 39 | 40 | inkProductsTable: 41 | Type: 'AWS::DynamoDB::Table' 42 | Properties: 43 | TableName: inkProductsTable 44 | AttributeDefinitions: 45 | - AttributeName: productId 46 | AttributeType: S 47 | KeySchema: 48 | - AttributeName: productId 49 | KeyType: HASH 50 | ProvisionedThroughput: 51 | ReadCapacityUnits: 5 52 | WriteCapacityUnits: 5 --------------------------------------------------------------------------------