diff --git a/db/handler.js b/db/handler.js new file mode 100644 index 0000000..e69de29 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2a95f6e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "aws-cloud-development-be", + "lockfileVersion": 2, + "requires": true, + "packages": {} +} diff --git a/products-service/.gitignore b/products-service/.gitignore new file mode 100644 index 0000000..2b48c8b --- /dev/null +++ b/products-service/.gitignore @@ -0,0 +1,6 @@ +# package directories +node_modules +jspm_packages + +# Serverless directories +.serverless \ No newline at end of file diff --git a/products-service/assets/event.json b/products-service/assets/event.json new file mode 100644 index 0000000..78726ce --- /dev/null +++ b/products-service/assets/event.json @@ -0,0 +1,123 @@ +{ + "body": "eyJ0ZXN0IjoiYm9keSJ9", + "resource": "/{proxy+}", + "path": "/products/", + "httpMethod": "get", + "isBase64Encoded": true, + "queryStringParameters": { + "id": "bfd21daa-ec93-11ec-8ea0-0242ac120002" + }, + "multiValueQueryStringParameters": { + "foo": [ + "bar" + ] + }, + "pathParameters": { + "id": "bfd22cdc-ec93-11ec-8ea0-0242ac120002" + }, + "stageVariables": { + "baz": "qux" + }, + "headers": { + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", + "Accept-Encoding": "gzip, deflate, sdch", + "Accept-Language": "en-US,en;q=0.8", + "Cache-Control": "max-age=0", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-Country": "US", + "Host": "1234567890.execute-api.us-east-1.amazonaws.com", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Custom User Agent String", + "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", + "X-Forwarded-For": "127.0.0.1, 127.0.0.2", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "multiValueHeaders": { + "Accept": [ + "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" + ], + "Accept-Encoding": [ + "gzip, deflate, sdch" + ], + "Accept-Language": [ + "en-US,en;q=0.8" + ], + "Cache-Control": [ + "max-age=0" + ], + "CloudFront-Forwarded-Proto": [ + "https" + ], + "CloudFront-Is-Desktop-Viewer": [ + "true" + ], + "CloudFront-Is-Mobile-Viewer": [ + "false" + ], + "CloudFront-Is-SmartTV-Viewer": [ + "false" + ], + "CloudFront-Is-Tablet-Viewer": [ + "false" + ], + "CloudFront-Viewer-Country": [ + "US" + ], + "Host": [ + "0123456789.execute-api.us-east-1.amazonaws.com" + ], + "Upgrade-Insecure-Requests": [ + "1" + ], + "User-Agent": [ + "Custom User Agent String" + ], + "Via": [ + "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)" + ], + "X-Amz-Cf-Id": [ + "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==" + ], + "X-Forwarded-For": [ + "127.0.0.1, 127.0.0.2" + ], + "X-Forwarded-Port": [ + "443" + ], + "X-Forwarded-Proto": [ + "https" + ] + }, + "requestContext": { + "accountId": "123456789012", + "resourceId": "123456", + "stage": "prod", + "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", + "requestTime": "09/Apr/2015:12:34:56 +0000", + "requestTimeEpoch": 1428582896000, + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "accessKey": null, + "sourceIp": "127.0.0.1", + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "Custom User Agent String", + "user": null + }, + "path": "/prod/path/to/resource", + "resourcePath": "/{proxy+}", + "httpMethod": "POST", + "apiId": "1234567890", + "protocol": "HTTP/1.1" + } +} diff --git a/products-service/assets/fixtures.js b/products-service/assets/fixtures.js new file mode 100644 index 0000000..7e6a5ce --- /dev/null +++ b/products-service/assets/fixtures.js @@ -0,0 +1,74 @@ +module.exports.products = [ + { + "count": 4, + "description": "Generates two continuously varying random voltages, two pulse actuated unpredictable voltages, and audio noise with three spectral distributions. ", + "id": "bfd21daa-ec93-11ec-8ea0-0242ac120002", + "price": 600, + "title": "Source of Uncertainty Model 266r Rev 3.0", + "image": "https://rss-react-shop-assets.s3.amazonaws.com/266.jpg" + }, + { + "count": 6, + "description": "Two independent voltage controlled oscillators, continuously tunable from 5Hz to 20kHz (applied control voltages can extend limits to .1Hz and 30kHz).", + "id": "bfd22282-ec93-11ec-8ea0-0242ac120002", + "price": 700, + "title": "Dual Oscillator Model 258c", + "image": "https://rss-react-shop-assets.s3.amazonaws.com/291.jpg" + }, + { + "count": 5, + "description": "It comprises four function generators organized in two pairs. All four generators can operate independently or can be linked in pairs to generate more complex output voltages", + "id": "bfd223c2-ec93-11ec-8ea0-0242ac120002", + "price": 650, + "title": "Quad Function Generator Model 281r", + "image": "https://rss-react-shop-assets.s3.amazonaws.com/281.jpg" + }, + { + "count": 4, + "description": "Four independent gates with selectable amplitude-dependents spectral characteristics.", + "id": "bfd224e4-ec93-11ec-8ea0-0242ac120002", + "price": 700, + "title": "Quad Lowpass Gate Model 292c Rev 3.0", + "image": "https://rss-react-shop-assets.s3.amazonaws.com/292.jpg" + }, + { + "count": 4, + "description": "Mixer/Preamplifier Model 207 includes a six channel stereo mixer with voltage-controlled panning and a single channel preamplifier with impedance and gain switches for a variety of input levels", + "id": "bfd22610-ec93-11ec-8ea0-0242ac120002", + "price": 600, + "title": "Mixer/Preamplifier Model 207r", + "image": "https://rss-react-shop-assets.s3.amazonaws.com/207.jpg" + }, + { + "count": 2, + "description": "Four independent sample-and-hold circuits, plus a specialized logic circuit for expediently implementing polyphonic patches.", + "id": "bfd2270a-ec93-11ec-8ea0-0242ac120002", + "price": 650, + "title": "Quad Sample And Hold Model 264m", + "image": "https://rss-react-shop-assets.s3.amazonaws.com/264.jpg" + }, + { + "count": 3, + "description": "Two bandpass filters with voltage-controlled center frequencies and bandwidths.", + "id": "bfd22822-ec93-11ec-8ea0-0242ac120002", + "price": 700, + "title": "Dual Voltage Controlled Filter Model 291r", + "image": "https://rss-react-shop-assets.s3.amazonaws.com/291.jpg" + }, + { + "count": 2, + "description": "Four independent sample-and-hold circuits, plus a specialized logic circuit for expediently implementing polyphonic patches.", + "id": "bfd22b60-ec93-11ec-8ea0-0242ac120002", + "price": 700, + "title": "Analogue Waveform Generator Model 25s", + "image": "https://rss-react-shop-assets.s3.amazonaws.com/25s.jpg" + }, + { + "count": 4, + "description": "The Model 259 Programmable Complex Waveform Generator introduces several innovative techniques for dealing with complex timbres.", + "id": "bfd22cdc-ec93-11ec-8ea0-0242ac120002", + "price": 950, + "title": "Programmable Complex Waveform Generator Model 259r", + "image": "https://rss-react-shop-assets.s3.amazonaws.com/259.jpg" + } +] diff --git a/products-service/functions/getProductById.js b/products-service/functions/getProductById.js new file mode 100644 index 0000000..09296f7 --- /dev/null +++ b/products-service/functions/getProductById.js @@ -0,0 +1,25 @@ +const { products } = require('../assets/fixtures'); + +module.exports.handler = async (event) => { + const productId = event.pathParameters.id; + const product = products.find(product => + product.id === productId + ); + + let body; + let statusCode; + + if (!product) { + statusCode = 404 + body = 'Error: Product not found' + } else { + statusCode = 200; + body = product; + } + + return { + statusCode, + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify(body) + }; +}; diff --git a/products-service/functions/getProductsList.js b/products-service/functions/getProductsList.js new file mode 100644 index 0000000..c4d5f0d --- /dev/null +++ b/products-service/functions/getProductsList.js @@ -0,0 +1,9 @@ +const { products } = require('../assets/fixtures'); + +module.exports.handler = async () => { + return { + statusCode: 200, + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify(products) + }; +}; diff --git a/products-service/serverless.yml b/products-service/serverless.yml new file mode 100644 index 0000000..b5146f9 --- /dev/null +++ b/products-service/serverless.yml @@ -0,0 +1,118 @@ +# Welcome to Serverless! +# +# This file is the main config file for your service. +# It's very minimal at this point and uses default values. +# You can always add more config options for more control. +# We've included some commented out config examples here. +# Just uncomment any of them to get that config option. +# +# For full config options, check the docs: +# docs.serverless.com +# +# Happy Coding! + +service: products-service +# app and org for use with dashboard.serverless.com +#app: your-app-name +#org: your-org-name + +# You can pin your service to only deploy with a specific Serverless version +# Check out our docs for more details +frameworkVersion: '3' + +provider: + name: aws + runtime: nodejs16.x + +# you can overwrite defaults here +# stage: dev +# region: us-east-1 + +# you can add statements to the Lambda function's IAM Role here +# iam: +# role: +# statements: +# - Effect: "Allow" +# Action: +# - "s3:ListBucket" +# Resource: { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "ServerlessDeploymentBucket" } ] ] } +# - Effect: "Allow" +# Action: +# - "s3:PutObject" +# Resource: +# Fn::Join: +# - "" +# - - "arn:aws:s3:::" +# - "Ref" : "ServerlessDeploymentBucket" +# - "/*" + +# you can define service wide environment variables here +# environment: +# variable1: value1 + +# you can add packaging information here +#package: +# patterns: +# - '!exclude-me.js' +# - '!exclude-me-dir/**' +# - include-me.js +# - include-me-dir/** + +functions: + getProductsList: + handler: functions/getProductsList.handler + events: + - httpApi: + path: /products + method: get + getProductById: + handler: functions/getProductById.handler + events: + - httpApi: + path: /products/{id} + method: get + +# - websocket: $connect +# - s3: ${env:BUCKET} +# - schedule: rate(10 minutes) +# - sns: greeter-topic +# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000 +# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx +# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx +# - iot: +# sql: "SELECT * FROM 'some_topic'" +# - cloudwatchEvent: +# event: +# source: +# - "aws.ec2" +# detail-type: +# - "EC2 Instance State-change Notification" +# detail: +# state: +# - pending +# - cloudwatchLog: '/aws/lambda/hello' +# - cognitoUserPool: +# pool: MyUserPool +# trigger: PreSignUp +# - alb: +# listenerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:listener/app/my-load-balancer/50dc6c495c0c9188/ +# priority: 1 +# conditions: +# host: example.com +# path: /hello + +# Define function environment variables here +# environment: +# variable2: value2 + +# you can add CloudFormation resource templates here +#resources: +# Resources: +# NewResource: +# Type: AWS::S3::Bucket +# Properties: +# BucketName: my-new-bucket +# Outputs: +# NewOutput: +# Description: "Description for the output" +# Value: "Some output value"