概要/背景
オンプレサーバ上の簡単な登録フォームをサーバレスっぽく作り直した
before
構成
- フォーム(html+js) + バリデーション/データ保存する APIという構成のアプリをN個のWEBサーバにデプロイしていた
- 各WEBサーバにAPIのコードとHTMLなどのアセットを配置
- サブミットされた登録内容はWEBサーバのローカルファイルに保存
いまいちだった点
- 各WEBサーバへのファイルのデプロイを手動で行っていた
- 登録データのファイルをN個のWEBサーバからコピーしないとすべてのデータが集まらない
after
構成
- 各WEBサーバにはプレースホルダのHTMLだけを配置
- HTMLの中身,JS, CSS, 画像などはS3から配信
- データ保存はfirebaseを使う
- fireabse上のデータのダンプと変換をaws lambdaで行う
- firebaseからダンプして
- JSONからCSVへ変換
- アクセス制限したS3バケットへアップロード
- URLをメール(SNS)で関係者に送信
- APIで行っていたバリデーションはfirebase rulesで実現
改善点
- S3上のファイルを更新すればコンテンツの更新ができる
- firebaseにデータを集約できる
- データの保存はfirebaseにまかせてコンテンツの作成に集中できる
- コンテンツの更新が複数サーバ上へのデプロイではなくS3 APIの操作で完結できる
まだいまいちな点
- データ量やトラフィック量によってはオンプレでの運用よりもお高くなる
- firebaseからダンプしてくるjsonファイルはエンジニア以外には扱いづらいので一工夫が必要
設定ファイルとか
package.json
"devDependencies": {
"babel": "^6.5.2",
"babel-loader": "^6.2.4",
"babel-plugin-transform-inline-environment-variables": "^6.5.0",
"babel-preset-es2015": "^6.6.0",
"css-loader": "^0.23.1",
"file-loader": "^0.8.5",
"html-loader": "^0.4.3",
"style-loader": "^0.13.1",
"url-loader": "^0.5.7",
"webpack": "^1.12.14",
"webpack-dev-server": "^1.14.1"
},
webpack.config.js
module.exports = {
context: __dirname,
entry: "./js/app.js",
output: {
path: "./dist/",
filename: "bundle.js"
},
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loader: "babel-loader"},
{test: /\.css$/, loader: 'style-loader!css-loader'},
{test: /\.(jpg|png|jpeg|gif|ttf|woff|woff2|svg|eot)$/, loader: 'url-loader'},
{test: /\.html$/, loader: 'html-loader'}
]
}
};
app.js(エントリポイント)
// CSSのロード
require('../css/some.css')
// HTMLをロード
const BODY = require('../body.html')
//<body>を置き換える
$(function(){
$('body').html(BODY);
})
index.html(プレースホルダHTML)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="<S3上のbundle.js>" charset="UTF-8"></script>
</head>
<body></body>
</html>
データの取得
curl -o https://<appId>.firebaseio.com/.json?auth=<SECRET>&print=pretty