LoginSignup
0
1

Fastify で 静的HTMLファイルのフロントエンドに書かれたロジックを AJAX を用いてバックエンドに移行するプロセス

Posted at

1. Fastify、AJAX とは

  • FastifyはAPIサーバーの構築に非常に適した高性能なNode.jsフレームワークです
  • AJAXとは、Asynchronous JavaScript and XMLの略称で、Web アプリケーションでデータを非同期的に転送する通信手法のことを指します

2. 内容:

静的HTMLファイルをFastifyを用いてホスティングします。さらにスクリプト内のロジックをAJAXを用いてバックエンドに移行することを実現できたので、その過程・内容についてまとめます。
題材はAtCoderの問題 ABC053Aを簡易なwebアプリにしたものです。

3. Fastify のインストール・実行・閲覧

Node.jsがインストールされていることを確認した上で、Fastifyをinstallします。

インストール

npm install fastify

実行

node server.js

閲覧

4. 元の静的HTML全体像

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>abc053a</title>
</head>

<body>
    <h1>abc053a</h1>
    <p>
        現在のレートxが1200未満かどうかで、参加するコンテスト(ABC/ARC)を選択し出力する。
    </p>
    <form id="squareForm">
        <label for="N">Select your rate:</label>
        <input type="range" name="N" id="N" min="0" max="4000" value="1200" required>
        <span id="rateValue">1200</span> <!-- Span to display selected value -->
        <br>
        <input type="submit" value="Submit">
    </form>

    <p id="output"></p>

    <script>
        // Get elements
        var slider = document.getElementById('N');
        var output = document.getElementById('rateValue');

        // Display the default value
        output.innerHTML = slider.value;

        // Update the current slider value (each time you drag the slider handle)
        slider.oninput = function () {
            output.innerHTML = this.value;
        };

        document.getElementById('squareForm').addEventListener('submit', function (event) {
            event.preventDefault(); // Prevent default form submission
            var N = parseInt(document.getElementById('N').value);

       ////////////////////////////バックエンドに移行される部分/////////////////////////////////////
            var ANS;
            if (N < 1200) {
                ANS = "ABC";
            } else {
                ANS = "ARC";
            }
       ////////////////////////////////////////////////////////////////////////////////////////////
            document.getElementById('output').innerText = "RATE: " + N + "\nCONTEST: " + ANS;

        });

    </script>

</body>

</html>

5. Fastifyで静的HTMLファイルをホスティングする

階層構造

project-root
├── public
│   └── index.html  : 元htmlをそのままコピペするだけ。
├── server.js
├── package.json

server.js

// server.js
const fastify = require('fastify')({ logger: true })
const path = require('path')
const fastifyStatic = require('@fastify/static')

/////////////////public/index.html設置に伴いこの部分が追加される////////////////////
// Register the static plugin
fastify.register(fastifyStatic, {
    root: path.join(__dirname, 'public'),
    prefix: '/', // optional: default '/'
})
/////////////////////////////////////////////////////////////////////////////////

// Start the server
const start = async () => {
    try {
        await fastify.listen({ port: 3000 })
        console.log('Server is running at http://localhost:3000')
    } catch (err) {
        fastify.log.error(err)
        process.exit(1)
    }
}
start()

6. フロントエンドに書かれたロジックを AJAX を用いてバックエンドに移行

public/index.html

    <script>
        // Get elements
        var slider = document.getElementById('N');
        var output = document.getElementById('rateValue');

        // Display the default value
        output.innerHTML = slider.value;

        // Update the current slider value (each time you drag the slider handle)
        slider.oninput = function () {
            output.innerHTML = this.value;
        };

        document.getElementById('squareForm').addEventListener('submit', function (event) {
            event.preventDefault(); // Prevent default form submission
            var N = parseInt(document.getElementById('N').value);

       ////////////////////////サーバーとの送受信をメソッドを記載//////////////////////////
       ////////////////////HTTP POSTメソッドを使用し値をrateというキーで送信。//////////////
            // Make an AJAX request to the backend
            fetch('/api/getContest', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ rate: N })
            })
        ///////////////////////サーバーからの応答をJSON形式にパース/////////////////////////
                .then(response => response.json())
                .then(data => {
                    document.getElementById('output').innerText = "RATE: " + data.rate + "\nCONTEST: " + data.contest;
                })
                .catch(error => console.error('Error:', error));
         //////////////////////////////////////////////////////////////////////////////

        });
    </script>

server.js

// server.js
const fastify = require('fastify')({ logger: true })
const path = require('path')
const fastifyStatic = require('@fastify/static')

// Register the static plugin
fastify.register(fastifyStatic, {
    root: path.join(__dirname, 'public'),
    prefix: '/', // optional: default '/'
})

///////////////////////////////////////////////////////////////
// Define the new endpoint
fastify.post('/api/getContest', async (request, reply) => {
    const { rate } = request.body
    let contest
    if (rate < 1200) {
        contest = 'ABC'
    } else {
        contest = 'ARC'
    }
    return { rate, contest }
})
///////////////////////////////////////////////////////////////

// Start the server
const start = async () => {
    try {
        await fastify.listen({ port: 3000 })
        console.log('Server is running at http://localhost:3000')
    } catch (err) {
        fastify.log.error(err)
        process.exit(1)
    }
}
start()

7. 全体の流れ

  • クライアントが /api/getContest エンドポイントに対して POST リクエストを送信します
  • サーバーは request.body から rate を取得します
  • rate の値に基づいて contest を設定します
  • { rate, contest } のオブジェクトをレスポンスとしてクライアントに返します

今回はFastify で 静的HTMLファイルのフロントエンドに書かれたロジックを AJAX を用いてバックエンドに移行することを通じて、バックエンドとの送受信の全体像が把握できました。

AJAXを用いる他のタスク(データベース操作、サーバーサイドの計算や処理、APIとの連携、など)も同様のアプローチで組めるはずです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1