Complete swap from express and aws to express and heroku due to the much smaller learning curve needed for a herkou build
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
#ignore all env files
|
||||
*.env
|
||||
node_modules
|
||||
@@ -0,0 +1,85 @@
|
||||
const Msg = require('../models/msg'); //import msg model
|
||||
|
||||
|
||||
//GET all messages
|
||||
const getAllMsg = (req, res) => {
|
||||
Msg.find({}, (err, data)=>{
|
||||
if (err){
|
||||
return res.json({Error: err});
|
||||
}
|
||||
return res.json(data);
|
||||
})
|
||||
};
|
||||
|
||||
//POST message
|
||||
const newMsg = (req, res) => {
|
||||
//check if the id already exists in db
|
||||
Msg.findOne({ id: req.body.id }, (err, data) => {
|
||||
|
||||
//if tea not in db, add it
|
||||
if (!data) {
|
||||
//create a new tea object using the Msg model and req.body
|
||||
const newMsg = new Msg({
|
||||
id:req.body.id,
|
||||
message: req.body.message,
|
||||
time: Date.now(),
|
||||
})
|
||||
|
||||
// save this object to database
|
||||
newMsg.save((err, data)=>{
|
||||
if(err) return res.json({Error: err});
|
||||
return res.json(data);
|
||||
})
|
||||
//if there's an error or the msg is in db, return an error message
|
||||
}else{
|
||||
if(err) return res.json(`Something went wrong, please try again. ${err}`);
|
||||
return res.json({message:"Msg already exists"});
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
//DELETE all messages
|
||||
const deleteAllMsg = (req, res) => {
|
||||
Msg.deleteMany({}, err => {
|
||||
if(err) {
|
||||
return res.json({message: "Deletion of all messages failed"});
|
||||
}
|
||||
return res.json({message: "Deletion of all messages successful"});
|
||||
})
|
||||
};
|
||||
|
||||
//GET message based on id
|
||||
const getOneMsg = (req, res) => {
|
||||
let id = req.params.id; //get the msg id
|
||||
|
||||
//find the specific msg with that id
|
||||
Msg.findOne({id:id}, (err, data) => {
|
||||
if(err || !data) {
|
||||
return res.json({message: "Message doesn't exist."});
|
||||
}
|
||||
else return res.json(data); //return the msg object if found
|
||||
});
|
||||
};
|
||||
|
||||
//DELETE message based on id
|
||||
const deleteOneMsg = (req, res) => {
|
||||
let id = req.params.id; // get the id of msg to delete
|
||||
|
||||
Msg.deleteOne({id:id}, (err, data) => {
|
||||
//if there's nothing to delete return a message
|
||||
if( data.deletedCount == 0) return res.json({message: "Message doesn't exist."});
|
||||
//else if there's an error, return the err message
|
||||
else if (err) return res.json(`Something went wrong, please try again. ${err}`);
|
||||
//else, return the success message
|
||||
else return res.json({message: "Message deleted."});
|
||||
});
|
||||
};
|
||||
|
||||
//export controller functions
|
||||
module.exports = {
|
||||
getAllMsg,
|
||||
newMsg,
|
||||
deleteAllMsg,
|
||||
getOneMsg,
|
||||
deleteOneMsg
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
<h1>Welcome to RESTapi Demo</h1>
|
||||
<p>Enjoy sending messages around</p>
|
||||
@@ -1,69 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var AWS = require('aws-sdk');
|
||||
|
||||
// Get "Hello" Dynamo table name. Replace DEFAULT_VALUE
|
||||
// with the actual table name from your stack.
|
||||
const helloDBArn = process.env['HELLO_DB'] || 'DEFAULT_VALUE'; //'Mark-HelloTable-1234567';
|
||||
const helloDBArnArr = helloDBArn.split('/');
|
||||
const helloTableName = helloDBArnArr[helloDBArnArr.length - 1];
|
||||
|
||||
// handleHttpRequest is the entry point for Lambda requests
|
||||
exports.handleHttpRequest = function(request, context, done) {
|
||||
try {
|
||||
const userId = request.pathParameters.userId;
|
||||
let response = {
|
||||
headers: {},
|
||||
body: '',
|
||||
statusCode: 200
|
||||
};
|
||||
|
||||
switch (request.httpMethod) {
|
||||
case 'GET': {
|
||||
console.log('GET');
|
||||
let dynamo = new AWS.DynamoDB();
|
||||
var params = {
|
||||
TableName: helloTableName,
|
||||
Key: { 'user_id' : { S: userId } },
|
||||
ProjectionExpression: 'email'
|
||||
};
|
||||
// Call DynamoDB to read the item from the table
|
||||
dynamo.getItem(params, function(err, data) {
|
||||
if (err) {
|
||||
console.log("Error", err);
|
||||
throw `Dynamo Get Error (${err})`
|
||||
} else if (data.Item) {
|
||||
console.log("Success", data.Item.email);
|
||||
response.body = JSON.stringify({ "email": data.Item.email.S });
|
||||
done(null, response);
|
||||
} else {
|
||||
console.log("Not found id=", userId);
|
||||
response.body = "Not found"
|
||||
response.statusCode = 404
|
||||
done(null, response);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'POST': {
|
||||
console.log('POST');
|
||||
let bodyJSON = JSON.parse(request.body || '{}');
|
||||
let dynamo = new AWS.DynamoDB();
|
||||
let params = {
|
||||
TableName: helloTableName,
|
||||
Item: {
|
||||
'user_id': { S: userId },
|
||||
'email': { S: bodyJSON['email'] }
|
||||
}
|
||||
};
|
||||
dynamo.putItem(params, function(error, data) {
|
||||
if (error) throw `Dynamo Error (${error})`;
|
||||
else done(null, response);
|
||||
})
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
done(e, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
const mongoose = require("mongoose"); //import mongoose
|
||||
|
||||
// msg schema
|
||||
const MsgSchema = new mongoose.Schema({
|
||||
id: {type:Number, required:true},
|
||||
message: {type:String, required:true},
|
||||
time: {type:Date, required:true}
|
||||
})
|
||||
|
||||
const Msg = mongoose.model('Msg', MsgSchema); //convert to model named Msg
|
||||
module.exports = Msg; //export for controller use
|
||||
Generated
+1769
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "restapi_demo",
|
||||
"version": "1.0.0",
|
||||
"description": "REST api written with express and run with heroku",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/gjcampbell777/RESTapi_demo.git"
|
||||
},
|
||||
"keywords": [
|
||||
"js",
|
||||
"express",
|
||||
"node",
|
||||
"heroku",
|
||||
"rest",
|
||||
"api"
|
||||
],
|
||||
"author": "Gregory Campbell",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/gjcampbell777/RESTapi_demo/issues"
|
||||
},
|
||||
"homepage": "https://github.com/gjcampbell777/RESTapi_demo#readme",
|
||||
"dependencies": {
|
||||
"compression": "^1.7.4",
|
||||
"dotenv": "^10.0.0",
|
||||
"express": "^4.17.1",
|
||||
"helmet": "^4.6.0",
|
||||
"mongoose": "^6.0.13",
|
||||
"multer": "^1.4.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
const express = require('express'); //import express
|
||||
const multer = require('multer');
|
||||
const upload = multer();
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
const msgController = require('../controllers/msg');
|
||||
|
||||
router.post('/msg', upload.none(), msgController.newMsg);
|
||||
|
||||
router.get('/msg', msgController.getAllMsg);
|
||||
router.post('/msg', msgController.newMsg);
|
||||
router.delete('/msg', msgController.deleteAllMsg);
|
||||
|
||||
router.get('/msg/:id', msgController.getOneMsg);
|
||||
//router.put('/msg/:id', msgController.updateMsg);
|
||||
router.delete('/msg/:id', msgController.deleteOneMsg);
|
||||
|
||||
module.exports = router; //export to use in server.js
|
||||
@@ -0,0 +1,37 @@
|
||||
require('dotenv').config({ path: 'development.env' });
|
||||
|
||||
const express = require('express');
|
||||
const routes = require('./routes/msg'); //import the routes
|
||||
const mongoose = require('mongoose'); //import mongoose
|
||||
const helemt = require('helmet'); //import helmet
|
||||
const compression = require('compression'); //import compression
|
||||
|
||||
const app = express();
|
||||
app.use(helmet());
|
||||
app.use(compression()); //compress all routes
|
||||
|
||||
mongoose.connect(
|
||||
process.env.MONGODB_URI,
|
||||
{
|
||||
server: { socketOptions: { keepAlive: 300000, connectTimeoutMS: 30000 } },
|
||||
replset: { socketOptions: { keepAlive: 300000, connectTimeoutMS : 30000 } },
|
||||
},
|
||||
(err) => {
|
||||
if (err) return console.log("Error: ", err);
|
||||
console.log("MongoDB Connection -- Ready state is:", mongoose.connection.readyState);
|
||||
}
|
||||
);
|
||||
|
||||
app.use(express.json()); //parses incoming requests with JSON payloads
|
||||
|
||||
app.use('/', routes); //to use the routes
|
||||
|
||||
app.route('/')
|
||||
.get(function (req, res) {
|
||||
res.sendFile(process.cwd() + '/index.html');
|
||||
});
|
||||
|
||||
const listener = app.listen(process.env.PORT || 3000, () => {
|
||||
console.log('App is listening on port ' + listener.address().port)
|
||||
})
|
||||
|
||||
-171
@@ -1,171 +0,0 @@
|
||||
---
|
||||
AWSTemplateFormatVersion: 2010-09-09
|
||||
|
||||
Description: API Gateway, Lambda, and Dynamo.
|
||||
|
||||
Resources:
|
||||
# Policy required for all lambda function roles.
|
||||
BaseLambdaExecutionPolicy:
|
||||
Type: AWS::IAM::ManagedPolicy
|
||||
Properties:
|
||||
Description: Base permissions needed by all lambda functions.
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- logs:CreateLogGroup
|
||||
- logs:CreateLogStream
|
||||
- logs:PutLogEvents
|
||||
- ec2:CreateNetworkInterface
|
||||
- ec2:DescribeNetworkInterfaces
|
||||
- ec2:DeleteNetworkInterface
|
||||
Resource: "*"
|
||||
|
||||
HelloTable:
|
||||
Type: AWS::DynamoDB::Table
|
||||
Properties:
|
||||
ProvisionedThroughput:
|
||||
ReadCapacityUnits: 5
|
||||
WriteCapacityUnits: 5
|
||||
AttributeDefinitions:
|
||||
- AttributeName: user_id
|
||||
AttributeType: S
|
||||
KeySchema:
|
||||
- AttributeName: user_id
|
||||
KeyType: HASH
|
||||
|
||||
# FIXME How to hook up custom domain?
|
||||
MyApiGateway:
|
||||
Type: AWS::ApiGateway::RestApi
|
||||
Properties:
|
||||
Name: !Sub "${AWS::StackName}-MyApiGateway"
|
||||
Description: A description
|
||||
FailOnWarnings: true
|
||||
Body:
|
||||
swagger: 2.0
|
||||
info:
|
||||
description: |
|
||||
The account API.
|
||||
version: 1.0
|
||||
basePath: /
|
||||
schemes:
|
||||
- https
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
paths:
|
||||
/users/{userId}/hello:
|
||||
get:
|
||||
description: TBD
|
||||
x-amazon-apigateway-integration:
|
||||
uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloLambda.Arn}/invocations"
|
||||
credentials: !GetAtt MyApiGatewayRole.Arn
|
||||
passthroughBehavior: when_no_match
|
||||
httpMethod: POST
|
||||
type: aws_proxy
|
||||
operationId: getHello
|
||||
parameters:
|
||||
- name: userId
|
||||
in: path
|
||||
description: TBD
|
||||
required: true
|
||||
type: string
|
||||
format: uuid
|
||||
post:
|
||||
description: TBD
|
||||
x-amazon-apigateway-integration:
|
||||
uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloLambda.Arn}/invocations"
|
||||
credentials: !GetAtt MyApiGatewayRole.Arn
|
||||
passthroughBehavior: when_no_match
|
||||
httpMethod: POST
|
||||
type: aws_proxy
|
||||
operationId: postHello
|
||||
parameters:
|
||||
- name: userId
|
||||
in: path
|
||||
description: TBD
|
||||
required: true
|
||||
type: string
|
||||
format: uuid
|
||||
- name: body
|
||||
in: body
|
||||
description: TBD
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- email
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
|
||||
MyApiGatewayDeployment:
|
||||
Type: AWS::ApiGateway::Deployment
|
||||
Properties:
|
||||
RestApiId: !Ref MyApiGateway
|
||||
StageName: prod
|
||||
|
||||
MyApiGatewayRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
AssumeRolePolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: apigateway.amazonaws.com
|
||||
Action: sts:AssumeRole
|
||||
Policies:
|
||||
- PolicyName: InvokeLambda
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- lambda:InvokeFunction
|
||||
Resource:
|
||||
- !GetAtt HelloLambda.Arn
|
||||
|
||||
HelloLambda:
|
||||
Type: AWS::Lambda::Function
|
||||
Properties:
|
||||
Role: !GetAtt HelloLambdaRole.Arn # TODO
|
||||
Handler: index.handleHttpRequest
|
||||
Runtime: nodejs12.x
|
||||
Environment:
|
||||
Variables:
|
||||
HELLO_DB: !Sub "arn:aws:dynamodb:${AWS::Region}:*:table/${HelloTable}"
|
||||
Code:
|
||||
ZipFile: |
|
||||
exports.handlers = function(event, context) {}
|
||||
HelloLambdaRole: # -> AppAPIRole
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
AssumeRolePolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: lambda.amazonaws.com
|
||||
Action: sts:AssumeRole
|
||||
ManagedPolicyArns:
|
||||
- !Ref BaseLambdaExecutionPolicy
|
||||
Policies:
|
||||
- PolicyName: getHello
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- dynamodb:GetItem
|
||||
Resource: !Sub "arn:aws:dynamodb:${AWS::Region}:*:table/${HelloTable}"
|
||||
- PolicyName: putHello
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- dynamodb:PutItem
|
||||
Resource: !Sub "arn:aws:dynamodb:${AWS::Region}:*:table/${HelloTable}"
|
||||
Reference in New Issue
Block a user