enebular クラウド実行環境で動作するシンプルなフォームの仕組みを作成してみる

ユーザーにデータを入力させるフォームは、さまざまな場面で利用する機会があります。今回は、enebularクラウド実行環境だけで動作するシンプルなフォームの仕組みの作成を体験してみます。わざわざサーバーを準備することなくフォームが使用でき、よりクラウド実行環境の使いどころが広がります。

image

このように、enebularクラウド実行環境(以降、クラウド実行環境)の仕組みだけで、シンプルにフォームを表示し、フォームデータを受信します。

クラウド実行環境の準備

以前の記事「新リリースのenebularクラウド実行環境の使い方」の「クラウド実行環境の準備」を参考に準備します。

HTTP トリガー設定

image

同様に以前の記事「クラウド実行環境での HTTP トリガーに設定する重複しない URL をつくる TIPS 」を参考にHTTP トリガー設定します。

Discover Flow からフローをインポート

今回のサンプルはこちらです。

lcdp-simple-form-sample

image

こちらのフローをインポートボタンをクリックして、宛先のプロジェクトを選択しインポートします。

image

インポート出来たらエディタで開いてみます。

image

「実行環境のパス名を自動取得」の change ノードをクリックします。

image

プロパティが開いたら完了ボタンをクリックします。

image

ノードの右上に青い丸が出てきて、フローを保存可能になります。

image

右上の保存ボタンをクリックして、フローをデプロイします。

フローの仕組み

フローの主な仕組みをご紹介します。

image

まず、LCDP in で入ってきたデータの流れから「実行環境のパス名を自動取得」の名前の change ノードで実行環境のパス名を自動で取得します。もし https://lcdp003.enebular.com/sample-001/ であれば sample-001 の部分です。

image

req.url で今回アクセスしてきた URL が分かるので、/ (スラッシュ) で split を使って文字を区切って 0 から数えて 1 番目の値を取得します。これで実行環境のパス名が取得できます。

image

次に「アクセスしたパスの分岐」の名前の change ノードの中で、アクセスしたパスに応じた分岐をしてます。

image

先ほどの実行環境のパス名を使って、それ以下のパスがフォームからのデータ送信である /postのパスか、それ以外の通常アクセスかを区別しています。

image

こちらはフォーム送信後以外の通常アクセス時の流れです。

image

LCDP 設定の change ノードの中では、LCDP out への Content-type の設定や、次の「フォーム HTML」という名前の template ノードに対して PostURL というフォーム送信後の URL を作成しています。

「フォーム HTML」という名前の template ノードは、以下のように HTML を返答しています。

<html>
<head>
  <title>入力フォーム</title>
  <!-- Bootstrap -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</head>
<body>
  <div class="container">
    <div class="mb-3">
      <h1>入力フォーム</h1>
    </div>
    <form method="POST" action="{{PostURL}}">
      <div class="mb-3">
        <label for="input1" class="form-label">名前</label>
        <input type="text" class="form-control" name="name" id="input1" placeholder="名前">
      </div>
      <div class="mb-3">
        <label for="input2" class="form-label">コメント</label>
        <textarea name="comment" class="form-control" id="input2" placeholder="コメント" cols="50" rows="5"></textarea>
      </div>
      <div class="mb-3">
        <label class="form-label">体調</label>
        <select name="condition" class="form-select">
          <option value="よい">よい</option>
          <option value="ふつう">ふつう</option>
          <option value="わるい">わるい</option>
        </select>
      </div>
      <div class="mb-3">
        <label class="form-label">公開するかどうか</label>
        <div class="form-check">
          <input class="form-check-input" type="radio" name="publish" value="OK" id="flexRadioOK">
          <label class="form-check-label" for="flexRadioOK">
            OK
          </label>
        </div>
        <div class="form-check">
          <input class="form-check-input" type="radio" name="publish" value="NG" id="flexRadioNG" checked>
          <label class="form-check-label" for="flexRadioNG">
            NG
          </label>
        </div>
      </div>
      <div class="mb-3">
        <input type="submit" class="btn btn-primary" value="送信する">
      </div>
    </form>
  </div>
</body>
</html>

ごくシンプルなフォームの仕組みですが、見た目の良いフォームの仕組みを使うために Bootstrap というフロントエンドのフレームワークの力を借りています。

Bootstrap のドキュメント を参考にすればフォームだけでなくレイアウトの仕組みを取り入れられるので色々と拡張しやすくしています。

image

つづいて、フォーム送信後にデータを受け取って結果を表示する部分です。

image

大事なのは「JSON としてフォームデータ取得」の function ノードです。

// Base64 でデータを変換
const parsedBase64Text = Buffer.from(msg.payload, 'base64').toString();

// パラメータとしてデコード
const parsedParamsText = decodeURIComponent(parsedBase64Text);

// JSON データにする
const items = parsedParamsText.split('&');

let jsonData = {};
for (let i = 0; i < items.length; i++){
    const itemText = items[i];
    const keyAndValue = itemText.split('=');
    const key = keyAndValue[0];
    const value = keyAndValue[1];
    jsonData[key] = value;
}

msg.payload = jsonData;

return msg;

enebular クラウド実行環境は AWS Lambda の仕組みを使っていて、フォーム送信で来たデータが base64 エンコードされた内容で受け取ってしまうので、Base64 のデータを変換をしてパラメータとしてデコードしたてから JSON データにしています。これで以降は JSON データでフォームデータを取得できます。

<html>
  <head>
    <title>送信完了</title>
    <!-- Bootstrap -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
  </head>
  <body>
    <div class="container">
      <div class="mb-3">
        <h1>送信完了!</h1>
      </div>
      <div class="mb-3">
        送信された内容
      </div>
      <div class="mb-3">
        <ul class="list-group">
          <li class="list-group-item">お名前 : {{payload.name}}</li>
          <li class="list-group-item">コメント : {{payload.comment}}</li>
          <li class="list-group-item">体調 : {{payload.condition}}</li>
          <li class="list-group-item">公開 : {{payload.publish}}</li>
        </ul>
      </div>
      <div class="mb-3">
        <a class="btn btn-primary" href="{{ReturnURL}}" role="button">フォームに戻る</a>
      </div>
    </div>
  </body>
</html>

結果の HTML も Bootstrap です。payload に入っているフォームから来た各データ name , comment , condition, publish を表示しています。

フローのデプロイ

フローをクラウド実行環境に反映します。

以前の記事「新リリースのenebularクラウド実行環境の使い方」の「フローのデプロイ方法」を参考にクラウド実行環境にフローをデプロイします。

HTTP トリガー URL 確認

準備ができたら HTTP トリガーの URL にアクセスしてみましょう。

image

このようにフォームが表示されます。

動作確認

シンプルにフォームを表示させ、フォームデータを受信してみましょう。

image

フォームのお名前・コメント・体調・公開の項目を、試しにこのような形で入力して送信するボタンをクリックします。

image

URL が 現在のHTTP トリガーURL/post に遷移してします。

image

フォームデータを受信した画面が表示されて、先ほど設定したお名前・コメント・体調・公開についてのデータが表示されています。

 

冒頭に説明したように、クラウド実行環境の仕組みだけでシンプルにフォームの表示とフォームデータの受信ができると、わざわざサーバーを準備することなくユーザーにデータ入力をさせる仕組みができるようになります。よりクラウド実行環境の使いどころが広がるので、今回の入り口となる仕組みをぜひ試してみてください。