はじめに
Azureを使ってなんか簡単なサンプルアプリでも作りたいなと思っていたところ、「Azureで「お問い合わせフォーム付きサイト」をサーバーレスで作ってみた!前編」という記事を見かけたので、自分でも実装してみました。
記事中ではCDNを使うことに多くの分量を割いていますが、今回の私の目的はAzure Functionsを使うことでしたので、CDNの部分は省略。また、言語もPowershellではなくNode.jsを使って実装することにしました。
環境
- 2020年6月21日時点でのAzure Functions
- Azure Functionsのランタイムバージョンは2.x系を使いました。
- see. Azure Functions ランタイム バージョンの概要 | Microsoft Docs
- Node.js 10.21.0
- Azure Functionsのランタイムバージョンに2.x系を使ったことからNodeは8.x系か10.x系に限られます。
- Node.js 14.x系で実行しようとしましたがローカルテストが起動しませんでした。
- nodebrew
- Node.jsを複数バージョン管理するためのツールです。
- 同種のツールは他にもたくさんあるみたいなのですが、とりあえず(macOSで)導入が楽そうなものを選びました。他意はありません。
セットアップ
最初のセットアップはAzure Functionsのチュートリアルに載っているので、それをなぞるだけです。
以降は、問い合わせフォームの実装に向けたTipsを記します。
フォームの準備
Azureで「お問い合わせフォーム付きサイト」をサーバーレスで作ってみた!前編 - ビジネスWebマガジン「Future Stride」|ソフトバンクの記事にあるように10 CSS HTML Form Designs – Sanwebeからのフォームデータをそのまま使いました。
フォームデータを分解する
フォームデータは項目名=値
を&
で組み合わせた文字列がreq.body
に入っているので以下のコードのように連想配列化しておきます。
const params = req.body.split('&'); let param_map = {}; params.forEach(param => { const param_item = param.split('='); param_map[param_item[0]] = decodeURI(param_item[1]); });
呼び出し元に返す
単純にJSONを呼び出し元に返すだけとしました。こんな実装になります。
context.res = { // status: 200, /* Defaults to 200 */ headers: {'Content-Type': 'text/json'}, body: JSON.stringify(param_map) };
出力バインディングの追加
以下の記事を参考に。
上記の記事中ではキューでしたが、今回はAzure Table Storageに格納したかったのでそのように設定します。
Azure Table Storageの準備
Azure Functionsを作ったときに作成されるStorageにテーブルを追加しておきます。上記の出力バインディングの追加時にtableName
で指定した名前をつけます。
Azure Table Storageにデータを登録する
以下の記事を参考に。
PartitionKey
とRowKey
に何をすればいいのかよく分かりませんでしたが、PartitionKey
はInquiry
に、RowKey
はDate.prototype.getTime()
を使ってミリ秒を返すようにしました。
あとはcontext.bindings.msg.push
の引数に登録するデータを格納した連想配列を渡します。まとめて以下のような実装になりました。
const now_date = new Date(); context.bindings.msg = []; param_map["PartitionKey"] = "Inquiry"; param_map["RowKey"] = now_date.getTime(); context.bindings.msg.push(param_map);
動作確認
実際に動作確認を取ります。フォームに値を入れて「Submit」ボタンをクリックすると...
Azure Table Storageに値が登録されました。
課題
とりあえずここまで動くものを作るのに半日かからない程度で実装できました。課題としては、
- 必須項目に値が入っているか否か・値の妥当性チェックなどの実施
- Azure Table Storageの
RowKey
の値の一意性確保 - SubmitボタンをクリックしたあとにJSONを返すだけでなく「お問い合わせありがとうございました」的なページを返したい
があります。が、そんなに難しい課題でもないような気がします。
運用上の課題としては、
- ログをどこから見たらいいかよくわからない
というものがあります。Application InsightsはAzure Functions作成時に同時に作られているのでこれと組み合わせたらいいのかなと思いますが、よく分かりませんでした。