Last active
July 23, 2019 23:29
-
-
Save yoonhoGo/8d7e914ba558375642e311ff723e5732 to your computer and use it in GitHub Desktop.
Node.js 서버리스 프레임웍을 사용하여 싱글페이지 포트폴리오 제작하기 7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const AWS = require('aws-sdk') | |
const express = require('express') | |
const bodyParser = require('body-parser') | |
/** | |
* 만약 profile을 쓰고 싶다면? | |
*/ | |
// if (process.env.STAGE === 'local') { | |
// const credentials = new AWS.SharedIniFileCredentials({profile: 'isMe'}); | |
// AWS.config.credentials = credentials; | |
// } | |
const dynamodb = new AWS.DynamoDB.DocumentClient({ | |
region: 'ap-northeast-2', | |
}) | |
const app = express() | |
app.use(bodyParser()) | |
app.post('/api/contact', (req, res, next) => { | |
if (!req.body.name) { | |
throw new Error('please give a param `name`.') | |
} else if (!req.body.subject) { | |
throw new Error('please give a param `subject`.') | |
} | |
next() | |
}, async (req, res) => { | |
const portfolioContect = await dynamodb.put({ | |
TableName: 'portfolio-contact', | |
Item: { | |
createdAt: Date.now(), | |
name: req.body.name, | |
email: req.body.email || undefined, | |
tel: req.body.tel || undefined, | |
subject: req.body.subject, | |
question: req.body.question || undefined, | |
}, | |
// ReturnValues: 'ALL_NEW', | |
}).promise() | |
res.json(req.body) | |
}) | |
module.exports = app |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const serverless = require('serverless-http') | |
const app = require('./api') | |
module.exports.handler = serverless(app) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html class="has-navbar-fixed-top"> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<title>Hello AUSG!</title> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css"> | |
<script defer src="https://use.fontawesome.com/releases/v5.1.0/js/all.js"></script> | |
</head> | |
<body> | |
<nav class="navbar is-black is-fixed-top" role="navigation" aria-label="main navigation"> | |
<div class="navbar-brand"> | |
<a class="navbar-item" href="#main"> | |
<img src="./static/images/AUSG_Branding-07.png" alt="AUSG: AWSKRUG University Student Group!"> | |
AUSG | |
</a> | |
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false"> | |
<span aria-hidden="true"></span> | |
<span aria-hidden="true"></span> | |
<span aria-hidden="true"></span> | |
</a> | |
</div> | |
<div class="navbar-menu"> | |
<div class="navbar-start"> | |
<!-- navbar items --> | |
<a class="navbar-item" href="#main"> | |
Home | |
</a> | |
<a class="navbar-item" href="#about"> | |
About | |
</a> | |
<a class="navbar-item" href="#contact"> | |
Contact | |
</a> | |
</div> | |
<div class="navbar-end"> | |
<!-- navbar items --> | |
<a class="navbar-item has-text-warning" href="http://www.awskr.org/"> | |
<span class="icon"> | |
<i class="fas fa-home"></i> | |
</span> | |
</a> | |
<a class="navbar-item has-text-white" href="https://github.com/AUSG"> | |
<span class="icon"> | |
<i class="fab fa-github"></i> | |
</span> | |
</a> | |
</div> | |
</div> | |
</nav> | |
<section class="hero is-fullheight is-warning" id="main"> | |
<div class="hero-body"> | |
<div class="container"> | |
<h1 class="title"> | |
Hello AUSG! | |
</h1> | |
<h2 class="subtitle"> | |
My first website with <strong>Bulma</strong>! | |
</h2> | |
</div> | |
</div> | |
</section> | |
<section class="hero is-fullheight is-dark" id="about"> | |
<div class="hero-body"> | |
<div class="container"> | |
<h1 class="title"> | |
About | |
</h1> | |
<h2 class="subtitle"> | |
안녕하세요. 저는 이번 발표를 맡은 고윤호라고 합니다.<br /> | |
AUSG 세미나에 오신걸 환영합니다. 부디 오신 기대만큼 가져가시는 시간 되시기 바랍니다. | |
</h2> | |
</div> | |
</div> | |
</section> | |
<section class="section" id="contact"> | |
<div class="container"> | |
<div class="field is-horizontal"> | |
<div class="field-label is-normal"> | |
<label class="label">From</label> | |
</div> | |
<div class="field-body"> | |
<div class="field"> | |
<p class="control is-expanded has-icons-left"> | |
<input class="input is-danger" type="text" placeholder="Name" id="name"> | |
<span class="icon is-small is-left"> | |
<i class="fas fa-user"></i> | |
</span> | |
</p> | |
<p class="help is-danger"> | |
This field is required | |
</p> | |
</div> | |
<div class="field"> | |
<p class="control is-expanded has-icons-left has-icons-right"> | |
<input class="input" type="email" placeholder="Email" id="email"> | |
<span class="icon is-small is-left"> | |
<i class="fas fa-envelope"></i> | |
</span> | |
</p> | |
</div> | |
</div> | |
</div> | |
<div class="field is-horizontal"> | |
<div class="field-label"></div> | |
<div class="field-body"> | |
<div class="field is-expanded"> | |
<div class="field has-addons"> | |
<p class="control"> | |
<a class="button is-static"> | |
+82 | |
</a> | |
</p> | |
<p class="control is-expanded"> | |
<input class="input" type="tel" placeholder="Your phone number" id="tel"> | |
</p> | |
</div> | |
<p class="help">Do not enter the first zero</p> | |
</div> | |
</div> | |
</div> | |
<div class="field is-horizontal"> | |
<div class="field-label is-normal"> | |
<label class="label">Subject</label> | |
</div> | |
<div class="field-body"> | |
<div class="field"> | |
<div class="control"> | |
<input class="input is-danger" type="text" placeholder="e.g. Partnership opportunity" id="subject"> | |
</div> | |
<p class="help is-danger"> | |
This field is required | |
</p> | |
</div> | |
</div> | |
</div> | |
<div class="field is-horizontal"> | |
<div class="field-label is-normal"> | |
<label class="label">Question</label> | |
</div> | |
<div class="field-body"> | |
<div class="field"> | |
<div class="control"> | |
<textarea class="textarea" placeholder="Explain how we can help you" id="question"></textarea> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="field is-horizontal"> | |
<div class="field-label"> | |
<!-- Left empty for spacing --> | |
</div> | |
<div class="field-body"> | |
<div class="field"> | |
<div class="control"> | |
<button class="button is-primary" type="submit" onclick="onContact()"> | |
Send message | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</section> | |
<footer class="footer"> | |
<div class="content has-text-centered"> | |
<p> | |
AUSG is Awesome Ultra Special Group. | |
</p> | |
</div> | |
</footer> | |
<script> | |
async function onContact() { | |
const data = JSON.stringify({ | |
name: document.getElementById('name').value, | |
email: document.getElementById('email').value, | |
tel: document.getElementById('tel').value, | |
subject: document.getElementById('subject').value, | |
question: document.getElementById('question').value, | |
}) | |
fetch('./api/contact', { | |
method: 'POST', | |
headers: { | |
'content-type': 'application/json' | |
}, | |
body: data, | |
}).then(response => alert('메시지 감사해요! 😄')) | |
.catch(error => alert('전송 실패했어요 😂')) | |
} | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
service: MyPortfolio | |
provider: | |
name: aws | |
runtime: nodejs8.10 | |
stage: ${opt:stage, 'dev'} | |
region: ap-northeast-2 | |
environment: | |
STAGE: ${self:provider.stage} | |
functions: | |
web: | |
handler: webHandler.handler | |
events: | |
- http: | |
path: / | |
method: ANY | |
cors: true | |
- http: | |
path: /{proxy+} | |
method: ANY | |
cors: true | |
api: | |
handler: apiHandler.handler | |
events: | |
- http: | |
path: /api | |
method: ANY | |
cors: true | |
- http: | |
path: /api/{proxy+} | |
method: ANY | |
cors: true | |
role: apiRole | |
resources: | |
Resources: | |
portfolioContactTable: # dynamodb table logicalName | |
Type: AWS::DynamoDB::Table | |
Properties: | |
TableName: portfolio-contact | |
AttributeDefinitions: | |
- AttributeName: createdAt | |
AttributeType: N | |
KeySchema: | |
- AttributeName: createdAt | |
KeyType: HASH | |
ProvisionedThroughput: | |
ReadCapacityUnits: 1 | |
WriteCapacityUnits: 1 | |
apiRole: | |
Type: AWS::IAM::Role | |
Properties: | |
RoleName: ApiRole | |
Path: "/portfolio/api/" | |
AssumeRolePolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
Effect: Allow | |
Principal: | |
Service: lambda.amazonaws.com | |
Action: sts:AssumeRole | |
Policies: | |
- PolicyName: root | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Action: | |
- logs:CreateLogGroup | |
- logs:CreateLogStream | |
- logs:PutLogEvents | |
Resource: arn:aws:logs:*:*:* | |
- PolicyName: forDynamo | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Action: | |
- dynamodb:PutItem | |
Resource: | |
Fn::GetAtt: portfolioContactTable.Arn # dynamodb table logicalName | |
plugins: | |
- serverless-offline |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express') | |
const app = express() | |
app.use('/static', (req, res) => { | |
const staticURI = 'https://raw.githubusercontent.com/yoonhoGo/serverless-spa-portfolio/master/static' | |
res.redirect(`${staticURI}${req.path}`) | |
}) | |
app.get('/', (req, res) => { | |
res.type('html').sendFile(__dirname + '/index.html') | |
}) | |
module.exports = app |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const serverless = require('serverless-http') | |
const app = require('./web') | |
module.exports.handler = serverless(app) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment