PCやスマホの画面にデータを表示したり、データを追加したりできるアプリをHTMLとCSSで記述します
7-1. WEBページの制作(HTML)
7-2. フロントWEBアプリのJavaScriptコード
7-3. バックエンドAPIアプリ(再掲)

7-1. WEBページの制作(HTML)
ファイル名は「index.html」とします
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ToDoアプリ</title>
<script type="text/javascript" src="crud.js"></script>
</head>
<body>
<h1>ToDoアプリ</h1>
<div id="server"></div>
<!-- 入力画面 -->
<p>やりたいこと:<input type="text" id="inputPlan" placeholder="計画を追加する"></p>
<p>実績 :<input type="text" id="inputResult" placeholder="補足があればメモする"></p>
<p>更新/削除するID :<input type="text" id="inputMyID" placeholder="更新または削除するID"></p>
<!-- レスポンス画面 -->
<div id="output"></div>
<!-- メニューボタン -->
<button onclick="itemAdd()">データを追加</button>
<button onclick="itemRead()">データを取得</button>
<button onclick="itemDelete()">データを削除</button>
<button onclick="itemUpdate()">データを更新</button>
</body>
</html>7-2. フロントWEBアプリのJavaScriptコード
ファイル名は「crud.js」とします
let server = "https://サーバーのURL/api3003";
// -------------------------------
// HTML
// -------------------------------
window.onload = function start() {
document.getElementById('server').innerHTML = '<p>' + server + '</p>';
}
// ----------------------------------------------
// データ読み取り
// ----------------------------------------------
async function itemRead() {
// API呼び出し実行
let url;
url = server + '/get';
const response = await fetch(url, {mode:'cors'});
const jsonObj = await response.json();
// HTML作成
let strFlag = "";
let html = '<table class="table table-bordered"><tr><th>ID</th><th>項目1</th><th>PLAN</th><th>MEMO</th><th>項目4</th></tr>';
jsonObj.forEach(item => {
if(item.flag == "0") {
strFlag = "<i class='bi bi-check-square-fill'></i>";
} else {
strFlag = "";
}
html += `<tr><td>${item.id}</td><td style="text-align:center;">${strFlag}</td><td>${item.plan}</td><td>${item.result}</td><td>`
+ `<button onclick="window.location.href='edit.html?`
+ `id=${item.id}&flag=${item.flag}&plan=${item.plan}&memo=${item.result}`
+ `';" class="btn btn-secondary">...</button>`
+ `${item.id}</td></tr>`;
});
html += '</table>';
document.getElementById('output').innerHTML = html;
}
// ----------------------------------------------
// データ作成
// ----------------------------------------------
async function itemAdd() {
// HTMLから要素を取得
var inputPlan = document.getElementById('inputPlan').value;
var inputResult = document.getElementById('inputResult').value;
console.log("Result:"+inputResult)
// API呼び出しを実行
const url = `${server}/create`;
const response = await fetch(url, {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
plan: inputPlan,
result: inputResult
})
});
// HTMLに結果を表示
let html = "データを書き込みました";
document.getElementById('output').innerHTML = html;
}
// ----------------------------------------------
// データ更新
// ----------------------------------------------
async function itemUpdate() {
// HTMLから要素を取得
var myID = document.getElementById('inputMyID').value;
var plan = document.getElementById('inputPlan').value.slice(0, 249);
var result = document.getElementById('inputResult').value.slice(0, 249);
if (!myID) {
document.getElementById('output').innerHTML = '<p>更新するIDが不足しています<i class="fa-solid fa-pen"></i></p>';
return;
}
// API呼び出しを実行
document.getElementById('output').innerHTML = '<p>データを変更しています<i class="fa fa-cog fa-spin fa-3x fa-fw"></i></p>';
const url = `${server}/update/${myID}`; // IDをURLパスに含める
const response = await fetch(url, {
method: "PUT",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
plan: plan,
result: result
})
});
// レコード更新が成功したか確認
if (!response.ok) {
throw new Error(`(updateName) APIサーバーに届きません。ステータス: ${response.status} ${response.statusText}`);
}
// レコード更新が成功した場合のメッセージ
let html = `レコード番号[${myID}]を更新しました`;
document.getElementById('output').innerHTML = html;
}
// ----------------------------------------------
// データ削除
// ----------------------------------------------
async function itemDelete() {
var targetID = document.getElementById('inputMyID').value;
if (targetID === '') {
document.getElementById('output').innerHTML = '<p>削除するIDが不足しています<i class="fa-solid fa-pen"></i></p>';
return;
}
document.getElementById('output').innerHTML = '<p>削除しています</p><i class="fa fa-cog fa-spin fa-3x fa-fw"></i>';
const url = `${server}/delete/${targetID}`; // IDをURLのパスに含める
const response = await fetch(url, {
method: "DELETE",
mode: "cors"
});
let html = `ID[${targetID}]を削除しました`;
document.getElementById('output').innerHTML = html;
}7-3. バックエンドAPIアプリ(再掲)
念のため、動作確認済みのNode.js で動くBFFを再掲します。ファイル名は「app-api.js」で、PM2でプロセスを起動しています。
// ----------------------------
// 初期設定:モジュール読み込み。変数定義。
// ----------------------------
const express = require("express"); // Expressモジュール読み込み
const app = express(); // アプリサーバーとしてインスタンス化
const mysql = require('mysql'); // MySQLモジュール読み込み
const cors = require('cors'); // CORS(Cross-Origin Resource Sharing)モジュールを読み込み
const port = 3003; // TCPポート番号を指定
require('dotenv').config(); //環境変数[~/app/.env]を process.env に代入
// ----------------------------
// `.bashrc` で設定した環境変数からユーザー情報を取得
// ----------------------------
// ----------------------------
// listen()メソッドを実行して3000番台ポートで待ち受け。
// ----------------------------
var server = app.listen(port, function(){
console.log("Node.js待ち受けポート:" + server.address().port);
});
// ----------------------------
// WEBブラウザは、異なるオリジン(ドメイン)へのアクセスは基本的にブロックする。
// CORS()関数は、リモートサーバーからのPOST, GET, PUT, DELETEメソッドのアクセスを許可する。詳細な制御も可能。
// ----------------------------
//app.use(cors({
// origin: 'https://example.com',
// methods: ['GET', 'POST', 'PUT', 'DELETE'],
// allowedHeaders: ['Content-Type', 'Authorization']
// }));
//app.use(cors());
// ----------------------------
// フォームデータを解析
// ----------------------------
app.use(express.urlencoded({ extended: true })); // フォーム形式(name=value)
app.use(express.json()); // JSON形式({ "key": "value" })
// ------------------------------------
// データベースに接続する関数
// ------------------------------------
function connectDatabase() {
const db = mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME
});
db.connect((err) => {
if (err) {
console.error('データベース接続失敗: ' + err.message);
throw err;
}
});
return db;
}
// ------------------------------------
// データベースを閉じる関数
// ------------------------------------
function closeDatabase(db) {
db.end((err) => {
if (err) {
console.error('データベース切断失敗: ' + err.message);
}
});
}
// ------------------------------------
// データ読み込み
// ------------------------------------
app.get('/get', (req, res) => {
// 1.データベースに接続
const db = connectDatabase();
// 2.データを読み出すクエリ
let sql = 'SELECT * FROM tbl_kano;';
db.query(sql, (err, results) => {
if (err) throw err;
res.json(results);
// 3.データベースを閉じる
closeDatabase(db);
});
});
// ------------------------------------
// データ書き込み
// ------------------------------------
app.post('/create', (req, res) => {
// 1.データベースに接続
const db = connectDatabase();
//plan memo
var inputPlan = req.body.plan;
var inputResult = req.body.result;
// 2.データを書き込むクエリ
sql = "INSERT INTO tbl_kano (plan, result, flag) VALUES ('" + inputPlan + "', '" + inputResult + "', 0)";
db.query(sql, (err, results) => {
if (err) {
console.log('DB書き込みに失敗 X');
throw err;
}
res.json(results);
console.log('DB書き込み成功 O');
});
// 3.データベースを閉じる
closeDatabase(db);
});
// ------------------------------------
// データ削除
// ------------------------------------
app.delete('/delete/:id', (req, res) => {
// 1.データベースに接続
const db = connectDatabase();
// 2.URLパラメータから `id` を取得(修正: `req.params.id` を使用)
let myID = req.params.id;
// IDが空ならエラーを返す
if (!myID) {
return res.status(400).json({ message: "削除するIDが指定されていません。" });
}
// SQLクエリを安全に実行
let sql = "DELETE FROM tbl_kano WHERE id = ?";
db.query(sql, [myID], (err, results) => {
if (err) {
console.error("DBのレコード削除に失敗:", err);
return res.status(500).json({ message: "データベースエラー" });
}
res.json({ message: `ID[${myID}] を削除しました`, data: results });
});
// 3.データベースを閉じる
closeDatabase(db);
});
// ------------------------------------
// データ更新
// ------------------------------------
app.put('/update/:id', (req, res) => {
// 1.データベースに接続
const db = connectDatabase();
// 2.URLパラメータから `id` を取得
let myID = req.params.id;
let myPlan = req.body.plan;
let myResult = req.body.result;
// リクエスト検査
if (!myID) {
console.log("更新するID[%d]が不足しています。", myID);
return res.status(400).json({ message: "更新するIDまたはデータが不足しています。" });
}
// SQLクエリを実行
let sql = "UPDATE tbl_kano SET plan = ?, result = ? WHERE id = ?";
db.query(sql, [myPlan, myResult, myID], (err, results) => {
if (err) {
console.error("レコードの更新に失敗:", err);
return res.status(500).json({ message: "データベースエラー" });
}
res.json({ message: `ID[${myID}] のデータを更新しました`, data: results });
});
console.log("[9]データベース更新を終了しDB閉じます");
// 3.データベースを閉じる
closeDatabase(db);
});
// ------------------------------------
// アプリサーバーが応答することを検査
// ------------------------------------
app.get('/', (req, res) => {
res.send('いえーい');
console.log('いえーい');
});