--- title: "アプリケーションのコーディング" url: https://docs.catalyst.zoho.com/ja/tutorials/alien-city-appsail/express/code-app/ description: "Catalyst AppSailサービスとCatalyst Data Storeを使用して、都市でのエイリアン遭遇を報告・検索できるアプリケーションを作成し、Catalystでホストします。" last_updated: 2026-10-30T17:47:18Z service: All Services type: tutorial related_links: - name: "AppSail用Catalyst SDK" url: /ja/cli/v1/initialize-resources/introduction/ --- # アプリケーションのコーディング プロジェクトのルートディレクトリに「**index.js**」ファイルを作成済みです。このファイルにはアプリケーションのバックエンドロジックが含まれます。 プロジェクトのルートディレクトリにフォルダを作成し、「**public**」と名付けます。このフォルダにはフロントエンドロジックのファイルが含まれます。publicフォルダ(`Alien City/public/`)内に以下のファイルを作成してください: * **index.html**:アプリケーションのフロントエンドのHTMLコードを含むファイルです。 * **main.js**:フロントエンドとバックエンドを接続するJavaScriptコードを含むファイルです。 以下は、**Alien City**プロジェクトの最終的なフォルダ構造です。 ![catalyst_alien_city_complete_dir](https://catalyst-docs-development.zohostratus.in/images/tutorials/alien-city-appsail-express/catalyst_alien_city_complete_dir.webp) `index.js`、`index.html`、および`main.js`ファイルをコーディングします。また、`app-config.json`ファイルも更新します。 > **Note:** このセクションのコードを確認し、内容を十分に理解してください。 以下のコードをコピーし、IDEを使用してプロジェクトの対応するファイルに貼り付けて保存してください。 **index.js** ```javascript var express = require('express'); var app = express(); var catalyst = require('zcatalyst-sdk-node'); app.use(express.json()); app.use(express.static('public')); const tableName = 'AlienCity'; // Data Storeに作成したテーブル const columnName = 'CityName'; // テーブルに作成したカラム app.post('/alien', (req, res) => { var cityJson = req.body; console.log(req.body) var catalystApp = catalyst.initialize(req); getDataFromCatalystDataStore(catalystApp, cityJson.city_name).then(cityDetails => { if (cityDetails.length == 0) { console.log("Alien alert!"); var rowData = {} rowData[columnName] = cityJson.city_name; var rowArr = []; rowArr.push(rowData); // Catalyst Data Storeテーブルに都市名を行として挿入する catalystApp.datastore().table(tableName).insertRows(rowArr).then(cityInsertResp => { res.send({ "message": "Thanks for reporting!" }); }).catch(err => { console.log(err); sendErrorResponse(res); }) } else { res.send({ "message": "Looks like you are not the first person to encounter aliens in this city! Someone has already reported an alien encounter here!" }); } }).catch(err => { console.log(err); sendErrorResponse(res); }) }); app.get('/alien', (req, res) => { var city = req.query.city_name; // Catalyst SDKを初期化する var catalystApp = catalyst.initialize(req); getDataFromCatalystDataStore(catalystApp, city).then(cityDetails => { if (cityDetails.length == 0) { res.send({ "message": "Hurray! No alien encounters in this city yet!", "signal": "negative" }); } else { res.send({ "message": "Uh oh! Looks like there are aliens in this city!", "signal": "positive" }); } }).catch(err => { console.log(err); sendErrorResponse(res); }) }); function getDataFromCatalystDataStore(catalystApp, cityName) { return new Promise((resolve, reject) => { // Catalyst Data Storeテーブルにクエリを実行する catalystApp.zcql().executeZCQLQuery("Select * from " + tableName + " where " + columnName + "='" + cityName + "'").then(queryResponse => { resolve(queryResponse); }).catch(err => { reject(err); }) }); } function sendErrorResponse(res) { res.status(500); res.send({ "error": "Internal server error occurred. Please try again in some time." }); } app.listen(process.env.X_ZOHO_CATALYST_LISTEN_PORT || 9000, () => { }) module.exports = app; ``` **index.html** ```xml <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>AlientCityAppClient</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"> </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"> </script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"> </script> <script src="main.js"> </script> </head> <body> <br> <br> <center> <h1>ALIEN CITY</h1> </center> <div class="container"> <ul class="nav nav-tabs" id="myTab" role="tablist"> <li class="nav-item"> <a class="nav-link active" id="check-tab" data-toggle="tab" href="#check" role="tab" aria-controls="check" aria-selected="true">Check My City</a> </li> <li class="nav-item"> <a class="nav-link" id="report-tab" data-toggle="tab" href="#report" role="tab" aria-controls="report" aria-selected="false">Report Alien Encounter</a> </li> </ul> <div class="tab-content" id="myTabContent"> <div class="tab-pane fade show active" id="check" role="tabpanel" aria-labelledby="check-tab"> <br> <br> <form> <div class="form-group"> <label for="city-get-input"> <b>Check if your city has aliens:</b> </label> <input type="text" class="form-control" id="city-get-input" aria-describedby="checkCity" placeholder="Enter City Name"> </div> <button type="submit" class="btn btn-primary" onclick="getAlienEncounter();return false;">Check</button> </form> <br> <br> <div id="result-container"> <div id="result-text"> </div> <br> <div id="result-image"> </div> </div> <div id="loader" style="display: none;"> <div class="spinner-border" role="status"> <span class="sr-only">Loading...</span> </div> </div> </div> <div class="tab-pane fade" id="report" role="tabpanel" aria-labelledby="report-tab"> <br> <br> <form> <div class="form-group"> <div class="city-post-input"> <label for="exampleInputEmail1"> <b>Enter the name of the city where you encountered an alien:</b> </label> <input type="text" class="form-control" id="city-post-input" aria-describedby="cityPost" placeholder="Enter City Name"> </div> </div> <button type="submit" class="btn btn-primary" onclick="postAlienEncounter();return false;">Report</button> </form> </div> </div> </div> </body> </html> ``` **main.js** ```javascript function postAlienEncounter() { debugger; var city = $("#city-post-input").val(); $.ajax({ url: "/alien", type: "post", contentType: "application/json", data: JSON.stringify({ "city_name": city }), success: function (data) { alert(data.message); }, error: function (error) { alert(error.message); } }); } function getAlienEncounter() { showLoader(); var positive = "https://media.giphy.com/media/Y1GYiLui9NHcxVKhdo/giphy.gif"; var negative = "https://media.giphy.com/media/fsPcMdeXPxSP6zKxCA/giphy.gif"; var city = $("#city-get-input").val(); $.ajax({ url: "/alien?city_name=" + city, type: "get", success: function (data) { console.log(data); $("#result-text").text(""); $("#result-text").text(data.message); var imagesrc = negative; if (data.signal == 'positive') { imagesrc = positive; } $("#result-image").html(""); $("#result-image").html("<img src='" + imagesrc + "' />"); hideLoader(); }, error: function (error) { alert(error.message); } }); } function showLoader() { $("#result-container").hide(); $("#loader").show(); } function hideLoader() { $("#loader").hide(); $("#result-container").show(); } ``` `app-config.json`ファイルのキー`command`の値を「**node index.js**」に更新します。これは、このプログラミングスタックとフレームワーク固有の[起動コマンド](https://docs.catalyst.zoho.com/ja/serverless/help/appsail/appsail-configurations/#起動コマンド)です。 **app-config.json** ```json { "command": "node index.js", "buildPath": "/Users/amelia-426/Catalyst/Alien City", // ビルドパスを指定してください "stack": "node24", "env_variables": {}, "memory": 256, "scripts": {} } ``` アプリケーションの動作を簡単に確認しましょう: 1. **GETオペレーション** * アプリケーションで都市名を入力して過去のエイリアン遭遇の記録を確認すると、`index.html`の**Check**ボタンのonClickイベントが`main.js`で定義された`getAlienEncounter()`関数をトリガーします。 * これにより、`index.js`関数で定義されたURLルートにAjaxコールが発行されます。 * `index.js`で定義された**GET API**が`getDataFromCatalystDataStore()`関数を呼び出し、リクエストクエリを渡します。 * この関数は、ZCQLクエリを実行してData Storeの**Alien City**テーブル内のデータを検索します。 * テーブルで都市名に一致する記録が見つかった場合、レスポンスとして*positive*シグナルが送信されます。見つからない場合は、*negative*シグナルが送信されます。 * クライアントはレスポンスに対応するメッセージを表示します。`main.js`で定義されたレスポンスに対応するGIFも表示されます。 2. **POSTオペレーション** * クライアントで都市名を入力してエイリアン遭遇を報告すると、`index.html`の**Report**ボタンのonClickイベントが`main.js`で定義された`postAlienEncounter()`関数をトリガーします。 * これにより、`index.js`関数で定義されたURLルートにAjaxコールが発行されます。`index.js`で定義されたPOST APIが`getDataFromCatalystDataStore()`関数を呼び出し、同じ都市名の記録が既に存在するかどうかを確認するリクエストクエリを渡します。 * この関数は、ZCQLクエリを実行してData Storeの**Alien City**テーブル内のデータを検索します。記録が既に存在する場合、レスポンスが送信され、アプリケーションはその都市名が既に追加されている旨のメッセージを表示します。 * 都市名の記録がない場合、ユーザーが入力した都市名で**Alien City**テーブルに新しい行が作成されます。クライアントにポップアップボックスが表示され、Data Storeへの記録の挿入が確認されます。適切なメッセージもログにプッシュされ、[Catalyst DevOps](https://docs.catalyst.zoho.com/ja/devops/)サービスの*Logs*コンポーネントから確認できます。