Azure Functionsを使った問い合わせフォームをNode.jsで実装する

はじめに

Azureを使ってなんか簡単なサンプルアプリでも作りたいなと思っていたところ、「Azureで「お問い合わせフォーム付きサイト」をサーバーレスで作ってみた!前編」という記事を見かけたので、自分でも実装してみました。

www.softbank.jp

記事中ではCDNを使うことに多くの分量を割いていますが、今回の私の目的はAzure Functionsを使うことでしたので、CDNの部分は省略。また、言語もPowershellではなくNode.jsを使って実装することにしました。

環境

  • 2020年6月21日時点でのAzure Functions
  • Node.js 10.21.0
    • Azure Functionsのランタイムバージョンに2.x系を使ったことからNodeは8.x系か10.x系に限られます。
    • Node.js 14.x系で実行しようとしましたがローカルテストが起動しませんでした。
  • nodebrew
    • Node.jsを複数バージョン管理するためのツールです。
    • 同種のツールは他にもたくさんあるみたいなのですが、とりあえず(macOSで)導入が楽そうなものを選びました。他意はありません。

セットアップ

最初のセットアップはAzure Functionsのチュートリアルに載っているので、それをなぞるだけです。

docs.microsoft.com

以降は、問い合わせフォームの実装に向けたTipsを記します。

フォームの準備

Azureで「お問い合わせフォーム付きサイト」をサーバーレスで作ってみた!前編 - ビジネスWebマガジン「Future Stride」|ソフトバンクの記事にあるように10 CSS HTML Form Designs – Sanwebeからのフォームデータをそのまま使いました。

f:id:miyohide:20200621175248p:plain

フォームデータを分解する

フォームデータは項目名=値&で組み合わせた文字列が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)
};

出力バインディングの追加

以下の記事を参考に。

docs.microsoft.com

上記の記事中ではキューでしたが、今回はAzure Table Storageに格納したかったのでそのように設定します。

Azure Table Storageの準備

Azure Functionsを作ったときに作成されるStorageにテーブルを追加しておきます。上記の出力バインディングの追加時にtableNameで指定した名前をつけます。

Azure Table Storageにデータを登録する

以下の記事を参考に。

docs.microsoft.com

PartitionKeyRowKeyに何をすればいいのかよく分かりませんでしたが、PartitionKeyInquiryに、RowKeyDate.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」ボタンをクリックすると...

f:id:miyohide:20200621175248p:plain

Azure Table Storageに値が登録されました。

f:id:miyohide:20200621181307p:plain

課題

とりあえずここまで動くものを作るのに半日かからない程度で実装できました。課題としては、

  • 必須項目に値が入っているか否か・値の妥当性チェックなどの実施
  • Azure Table StorageのRowKeyの値の一意性確保
  • SubmitボタンをクリックしたあとにJSONを返すだけでなく「お問い合わせありがとうございました」的なページを返したい

があります。が、そんなに難しい課題でもないような気がします。

運用上の課題としては、

  • ログをどこから見たらいいかよくわからない

というものがあります。Application InsightsはAzure Functions作成時に同時に作られているのでこれと組み合わせたらいいのかなと思いますが、よく分かりませんでした。

実装例

github.com