2023/12/20

Node.js 製作呼叫 Express 的前端網站

作者:吳祐賓

 


 

 

後端網站已經完成,前端要怎麼和後端連線和除錯?難道需要先將後端網站放上線,再開發前端去和上線後端連線並除錯。如果後端有錯誤時再回到後端專案來除錯?來看看這個前端範例來如何解決問題吧。


 

建立前端網站目錄及環境

建立一個目錄,本範例建立 "my_es6" 目錄。在專案根目錄下初始化npm:

npm init -y


 

安裝 Webpack 和相關套件:

npm install --save-dev webpack webpack-cli

 

安裝 webpack-dev-server:

npm install webpack-dev-server@latest --save-dev


安裝 html-webpack-plugin:

npm install html-webpack-plugin --save-dev


安裝Babel相關套件,用於轉譯ES6語法:

npm install --save-dev @babel/core @babel/preset-env babel-loader

 

建立 ".babelrc" 檔案,並配置 Babel:

{
  "presets": ["@babel/preset-env"]
}

在專案根目錄下建立 Webpack 配置檔(本例為:webpack.config.js):

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: {
    main: './src/index.js',
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
    },
    port: 8080,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        },
      },
    ],
  },
};


建立 public 目錄及 index.html 檔案,將以下內容貼上:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Your ES6 Website</title>
</head>
<body>
  Hello world
    <div id="app"></div>
</body>
</html>


建立 src 目錄,並在 src 目錄下建立你的網站入口文件(本例為:index.js),將以下 ES6 程式碼貼到這個檔案裡:

// src/index.js
const greeting = () => {
  console.log('Hello, webpack with ES6!');
};

greeting();

在 package.json 中新建腳本:

"scripts": {
   ...
   "build": "webpack",
   "start": "webpack-dev-server --open",
}

這個設定中的 --open 選項會在啟動時自動打開瀏覽器。

 

執行腳本,啟動網站:

npm run start

此命令會使用 webpack-dev-server 啟動本地開發伺服器,並且在瀏覽器中開啟你的網頁應用程式。 

 

若要發佈網站時,建構網站的指令:

npm run build

Webpack 將處理你的 ES6 程式碼,使用 Babel 進行轉譯,並在 dist 目錄下產生 bundle.js。你可以將 bundle.js 引入到你的 HTML 文件中,以在瀏覽器中運行你的網站。下圖是成功運行的圖片:


 

 建立呼叫後端 API 的程式及畫面

 

 在 webpack 設定檔中 devServer 設定區堿調整如下:

  devServer: {
    static: {
      directory: path.join(__dirname),
    },
    port: 8080,
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '^/api': '' },
        changeOrigin: true,
        secure: false,
      },
    },
  },

這裡的 proxy 設定會把所有 /api/* 的請求導向到 http://localhost:3000。pathRewrite 用來把請求路徑中的 /api 前綴去除,以符合目標伺服器的預期路徑。changeOrigin 設為 true,這樣就會修改請求頭的 Host 欄位,指向目標伺服器。secure 設為 false 可以禁用 SSL 證書驗證,在開發環境中可能會很有用。


 

修改 index.html 內容:


<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Your ES6 Website</title>
</head>
<body>
  <h1>Webpack Front Site Project</h1>
    <div id="app"></div>
    <div id="contentdiv">
      <table>
        <tr>
          <td>
            <input id="valueField" type="text" value="A B C" />
          </td>
          <td>
            <button id="btnReverse">
              ReverseString
            </button>
          </td>
        </tr>
      </table>
    </div>
</body>
</html>

 

 修改 index.js 內容

 

 // src/index.js
function onReverseStringClick() {
  const valueField = document.getElementById('valueField');
  const inputValue = valueField.value;

  // 使用 Fetch API 來呼叫伺服器端的 /api/reverse_string
  fetch('/api/reverse_string/' + inputValue, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
    },
  })
  .then(response => response.json())
  .then(data => {
    // 處理伺服器回傳的資料
    const valueField = document.getElementById('valueField');
    valueField.value = data.result;
    console.log('Reversed String:', data.result);
  })
  .catch(error => {
    console.error('Error:', error);
  });
}

const greeting = () => {
    console.log('Hello, webpack with ES6!');
  };
 
greeting();

const app = document.getElementById('app');
app.innerHTML = '<h1>Hello, Webpack!</h1>';

document.getElementById('btnReverse').addEventListener('click', onReverseStringClick);


這段程式碼主要是一個簡單的前端 JavaScript 應用程式,使用了現代的 ES6 語法和 Fetch API 來與後端伺服器進行通訊。以下是程式碼的大致解說:

    onReverseStringClick 函式:這是當按鈕被點擊時觸發的事件處理器。它首先從網頁中取得一個 id 為 'valueField' 的輸入元素,然後獲取該元素的值,並使用 Fetch API 發送 GET 請求到伺服器的 /api/reverse_string 路徑。接著,它處理伺服器回傳的 JSON 資料,將反轉後的字串顯示在 'valueField' 輸入元素中,並在控制台輸出反轉後的字串。

    greeting 函式:這是一個簡單的箭頭函式,僅在控制台輸出 "Hello, webpack with ES6!"。

    app 元素:這裡使用 document.getElementById 取得 id 為 'app' 的元素,並修改其 innerHTML 屬性,插入一個包含 "Hello, Webpack!" 的標題標籤。

    事件監聽器:這裡使用 document.getElementById 取得 id 為 'btnReverse' 的按鈕元素,然後對其添加一個點擊事件監聽器,當按鈕被點擊時,將觸發 onReverseStringClick 函式。

最後,重新啟動網站。下圖為完成後可能的畫面。

總結

到目前為止已經將後端和前端快速地製作完成,程式相當簡單,相信任何人經過這套教學流程都能很快將前後端串連起來。期待你能利用這套簡易全端架構再創造出屬於你的網頁應用程式。

和你分享。


See also

文首圖片來源:攝影師:Ketut Subiyanto: https://www.pexels.com/zh-tw/photo/4560148/

2023/12/18

Express 的 Basic Authentication 實作

作者:吳祐賓


 

 Express 框架本身並未內建基本身份驗證(Basic Authentication)的功能,但你可以使用第三方的中介軟體(middleware)來實現。一個常見的方式是使用 basic-auth 這個 npm 套件。以下是一個簡單的範例:

首先,安裝 basic-auth 套件:

 npm install basic-auth



然後,在你的 Express 應用程式中使用它:

 

const auth = require('basic-auth');

// 中介軟體函式,用於進行基本身份驗證
const basicAuth = (req, res, next) => {
  const credentials = auth(req);

  if (!credentials || credentials.name !== 'username' || credentials.pass !== 'password') {
    res.setHeader('WWW-Authenticate', 'Basic realm="example"');
    res.status(401).send('Authentication required');
    return;
  }

  // 認證成功,繼續處理下一個中介軟體或路由
  next();
};


// 使用中介軟體進行基本身份驗證
app.use(basicAuth);


這個範例中,我們引入了 basic-auth 套件,並建立一個自定義的中介軟體 basicAuth 用於進行基本身份驗證。當瀏覽其它任何路由時,會先使用 app.use(basicAuth) 將中介軟體套用到所有路由之前,進行身份驗證。你可以將 'username' 和 'password' 替換為實際的使用者名稱和密碼。

請注意,基本身份驗證的方式相對簡單,建議在實際應用中使用更強大的身份驗證機制,例如 JSON Web Tokens(JWT)或 OAuth。

使用基本身份驗證是在開發時可以很快速的有個驗證機制,之後要替換也很快速。

 

接下來呢?

你可以在 basicAuth 時先使用 session 檢查,如果已經登入就不再需要經過基本身份驗證。大概如下面的程式範例。

const basicAuth = (req, res, next) => {
    if (req.session.user) {
        next();
        return;
    }

總結

Basic Authentication 基本身份驗證是多數 Web API 服務所支援的基礎驗證技術(就如它的名字一樣),由於是明碼在網路上傳輸,所以安全性來說相對較低。若實戰要使用時請務必使用加密傳輸 (https),才能確保其服務的安全。

不過在開發的過程一直要驗證也是挺麻煩的,所以驗證功能通常會在專案的最後再上線。提供您參考。

 

和你分享。

 

 

 See also

 文首圖片來源:攝影師:Life Of Pix: https://www.pexels.com/zh-tw/photo/4291/

2023/12/15

使用 Swagger UI 來為你的 Express 應用程式中的路由生成 API 說明文件

作者:吳祐賓

 


 

 

使用 Swagger UI 來為你的 Express 應用程式中的路由生成API說明文件。Swagger UI 提供了一個直觀且互動的方式,讓開發者能夠查看和測試你的 API。

以下是如何將 Swagger UI 整合到你的 Express 應用程式中的基本步驟: 


安裝 Swagger UI 套件

使用以下指令安裝:

npm install swagger-jsdoc swagger-ui-express



設定 Swagger 設定檔案:

在你的專案中建立一個 swagger.js 檔案,用於配置 Swagger UI。例如:

const swaggerJsdoc = require('swagger-jsdoc');

const options = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: 'Express API with Swagger',
      version: '1.0.0',
      description: 'Documentation for Express API',
    },
  },
  apis: ['./app/*.js'], // 指定 API 路徑,這裡可能需要調整
};

const specs = swaggerJsdoc(options);

module.exports = specs;



設定 Swagger UI 中介軟體:

在 server.js 中,加入以下程式碼:

const express = require('express');
const swaggerUi = require('swagger-ui-express');
const specs = require('./swagger');

const app = express();

// ... 其他程式碼 ...

// 設定 Swagger UI 中介軟體
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));

const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}/`);
});

在這裡,我們將 Swagger UI 中介軟體掛載到 /api-docs 路徑上,它將使用先前定義的 Swagger 設定檔案(specs)。



註解你的路由:

在 server.js 檔案中,使用 Swagger 註解來描述每個路由的信息。以下是一個簡單的範例:

/**
 * @swagger
 * tags:
 *   name: Strings
 *   description: Operations related to strings
 */

/**
 * @swagger
 * /echo_string/{value}:
 *   get:
 *     summary: Echoes the input string
 *     tags: [Strings]
 *     parameters:
 *       - in: path
 *         name: value
 *         required: true
 *         description: The string to be echoed
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Successful response
 *         content:
 *           application/json:
 *             example: { result: "input_string" }
 */

app.get('/echo_string/:value', (req, res) => {
  res.json({ result: serverMethods.echoString(req.params.value) });
});

/**
 * @swagger
 * /reverse_string/{value}:
 *   get:
 *     summary: Reverses the input string
 *     tags: [Strings]
 *     parameters:
 *       - in: path
 *         name: value
 *         required: true
 *         description: The string to be reversed
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Successful response
 *         content:
 *           application/json:
 *             example: { result: "gnirts_tupni" }
 */

app.get('/reverse_string/:value', (req, res) => {
  res.json({ result: serverMethods.reverseString(req.params.value) });
});

這樣的註解會被 Swagger 解析,並顯示在 Swagger UI 中。



執行應用程式:

最後,執行 node server.js,並瀏覽網址 http://localhost:3000/api-docs,你應該能夠看到 Swagger UI,其中包含你的 API 說明文件。畫面應該長得像下圖的圖片。



這樣就完成了 Swagger UI 的整合。透過 Swagger,你能夠更容易地為你的 API 提供說明文件,並讓開發者更容易了解和使用你的 API。


和你分享。


See also

文首圖片來源:攝影師:Karolina Grabowska: https://www.pexels.com/zh-tw/photo/4476376/


2023/12/13

Express 加入 Session 機制

作者:吳祐賓



這篇文章會介紹 Express 加入 Session 中介軟體後具備狀態管理能力,處理機敏資料來說,Session 仍是一個還蠻不錯的機制,不一定需要全有或是全無。接下來帶您一步一步將 Session 功能建立起來。

安裝 express-session 套件

express-session 安裝是在 Terminal 下輸入以下指令:

npm install express-session


 

建立 Session 中介軟體

建立 Session 中介軟體讓每個 request 進來時都要先經過它來處理及管理 session。將以下的程式碼複製到 server.js 裡。



const session = require('express-session');

// 設定 express-session 中介軟體
app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: true,
}));


以下是對這段程式碼的解釋:

  1. express-session 是一個 Express 中的中介軟體,它用於管理用戶的會話,並將會話資訊存儲在伺服器端。這是一種在無狀態的 HTTP 協議上實現有狀態的解決方案。

  2. app.use(session(...)):這行程式碼使用 app.use 方法將 express-session 中介軟體套用到 Express 應用程式中。這確保在每個請求進入伺服器之前,express-session 中介軟體都會處理和管理會話。

  3. 中介軟體的設定選項:

    • secret:這是一個字串,用於簽署(sign)用戶會話,以防止被竄改。應該是一個安全的隨機字串,這是確保會話安全性的一部分。
    • resave:如果為 true,則每次請求進來時都會重新保存會話,即使是未修改的。這通常設置為 false,以避免不必要的會話存儲操作。
    • saveUninitialized:如果為 true,則未初始化的會話也會被保存。未初始化的會話是指新會話但未被修改的會話。通常設置為 true

這段程式碼確立了一個基本的 express-session 配置,以啟用用戶會話的管理功能。這樣,當用戶進行登入等操作時,你就可以使用 req.session 物件來存儲和訪問相關的會話資訊。底下可以看到使用 session 前和使用 session 後的 response 內容。


使用 session 前

使用 session 後


總結

使用 session 中介軟體可以使 Express RESTful 服務提供會話機制,在日後如果要管理使用者狀態是一個不可或缺的套件,而透過實作可以知道,要在 Express 上建立中介軟體也是一件非常簡單的事。我們之後在深入開發時還會再用到它。


和你分享。


See also

文首圖片來源: 攝影師:SHVETS production: https://www.pexels.com/zh-tw/photo/7176317/

2023/12/11

Express 建立 echoString 和 reverseString 方法

作者:吳祐賓






上一節提到 Node.js 搭配 Express 就能很快速的製作做 RESTful API 服務,這次要來新增服務模組。

建立 servermethods.js 模組

打開上一節的專案,在 app 目錄中建立 servermethods.js,將以下程式碼貼上去:

// servermethods.js

function echoString(aValue){
    return aValue;
}

function reverseString(aValue){
    return aValue.split("").reverse().join("");
}

module.exports = {
    echoString,
    reverseString
}


這是一個簡單的 Node.js 模組,檔名為 servermethods.js。以下是程式解說:

  1. 模組導出:
    module.exports 這一行將兩個函式 echoStringreverseString 導出,讓其他檔案可以引入這個模組並使用這兩個函式。

  2. echoString 函式:
    這個函式接收一個參數 aValue,然後直接將它回傳。換句話說,這個函式的作用是傳回接收到的值,不作任何處理。

  3. reverseString 函式:
    這個函式也接收一個參數 aValue,但是它做了一些處理。首先,它使用 split("") 方法將接收到的字串轉換為一個字元陣列。接著,使用 reverse() 方法將這個字元陣列反轉。最後,使用 join("") 方法將反轉後的字元陣列重新組合成字串。簡單來說,這個函式的目的是將傳入的字串進行反轉操作,並將結果回傳。

這個模組提供了兩個簡單的函數,一個是直接回傳傳入值的 echoString 函數,另一個是將傳入字串進行反轉的 reverseString 函數。這樣的模組可以在其他地方引入,並使用這兩個函式進行相應的操作。

 
 

建立使用 serverMethods 的路由

打開 server.js 檔案,將以下程式貼到裡面。

// 引入 servermethods 模組
const serverMethods = require('./app/servermethods');

//...

app.get('/echo_string/:value', (req, res) => {
  res.json(serverMethods.echoString(req.params.value));
});

app.get('/reverse_string/:value', (req, res) => {
  res.json(serverMethods.reverseString(req.params.value));
});
 
 

這段程式碼繼承上一節 server.js,透過 Express 框架實現了兩個 API 端點。以下是程式解說:

  1. 引入模組:
    使用 require('./app/servermethods') 引入了名為 servermethods 的模組。該模組包含了兩個函式,分別為 echoStringreverseString

  2. 路由設定:
    使用 Express 框架的 app.get 方法設定了二個不同的路由:

    • /echo_string/:value 路由:當收到這個路由的 HTTP GET 請求時,會呼叫 serverMethods.echoString 函式,將請求參數中的值傳入函式,然後將函式的結果以 JSON 格式回傳給客戶端。

    • /reverse_string/:value 路由:當這個路由收到 HTTP GET 請求時,會呼叫 serverMethods.reverseString 函式,將請求參數中的值傳入函式,然後以 JSON 格式回傳函式的結果。

  3. 回應結果:
    路由處理都使用 res.json 方法回傳 JSON 格式的結果給客戶端,serverMethods.echoStringserverMethods.reverseString 這兩個函式的結果會被包裝在一個具有 result 屬性的 JSON 物件中。

簡單來說,我們做了兩個簡單的 API 端點,一個是回傳接收到的字串,另一個是回傳反轉後的字串。這些 API 可以在應用程式中被其他端點或前端應用程式所使用。

最後在 Terminal 輸入 "node server.js" 啟動 RESTful 服務,使用

  • http://localhost:3000/echo_string/A B C
  • http://localhost:3000/reverse_string/A B C

就可以看到類似下圖的結果。


 

 

總結

這個範例主要是將之前常看到的啟動範例復刻到 Express 上,實作上也相當簡單,servermethods.js 提供 echoString、reverseString 兩個文字處理函式;server.js 增加兩個路由來呼叫 servermethods.js 的函式並回傳結果。此範本很適合未來新專案的起手式。

和你分享。


See also

首圖由Gerd AltmannPixabay上發布

2023/12/08

Node.js 製作 RESTful API 服務 (含 Express 套件介紹)

作者:吳祐賓 

 


 

這期要來開始製作第一個 Http 服務程式。首先,先建立一個名為 "HelloHttp" 資料夾。


在資料夾新建專案 - 初始化專案

Node.js 新建專案的方式叫「初始化專案」,使用 Terminal 在前面建立的 HelloHttp 資料夾輸入:

npm init


輸入完成後 npm 會啟動互動式介面詢問我們這個專案的基本資料,原則上可以一直按 ENTER 來輸入預設值,這裡由於我的進入點想和一般網頁區隔,以便於識別服務的入口,所以命名為 "server.js"。完成後會在專案目錄下建立 package.json。



建立並編輯 server.js

接著使用編譯器新增 "server.js",並將底下的程式碼複製到該檔案中並存檔。

// 引入 http 模組
const http = require('http');

// 建立一個 HTTP 伺服器
const server = http.createServer((req, res) => {
  // 處理請求
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello, World!\n');
});

// 監聽 3000 port
const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}/`);
});

 

啟動第一支 Http 服務

使用以下指令來啟動服務。啟動服務後再開啟瀏覽器,在網址列輸入:http://localhost:3000,就可以看到如下圖的結果。

node server.js

 


 

建立計算機模組

在專案資料夾建立 "app" 目錄,並建立 "calc.js" 檔案,將底下的程式碼貼上後存檔。

// app/calc.js
function add(a, b) {
    return a + b;
}

module.exports = {
    add,
};

 

增加 sum 路由

修改 http.createServer 內的程式,加入 /sum 路由,並且讀取 request 裡的參數 a 和 參數 b,接著呼叫 add 函式將 a 和 b 加總,加總結果寫入 json 物件並回傳給客戶端。修改的程式碼可能長成下面的模樣。

// 引入 http 模組
const http = require('http');
const url = require('url');

// 引入 calc 模組
const calc = require('./app/calc');

// 建立一個 HTTP 伺服器
const server = http.createServer((req, res) => {
  // 解析 URL
  const parsedUrl = url.parse(req.url, true);

  // 處理路由
  if (parsedUrl.pathname === '/sum' && req.method === 'GET') {
    // 取得 URL 參數
    const { a, b } = parsedUrl.query;

    // 將字串轉為數字
    const numA = parseInt(a, 10);
    const numB = parseInt(b, 10);

    // 使用 calc 模組計算結果
    const result = calc.add(numA, numB);

    // 回傳結果
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ result }));
  } else {
    // 其它路由都回傳 Hello World
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello, World!\n');
  }
});

// 監聽 3000 port
const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}/`);
});

程式運行結果

 

 

建立第一個 Http 服務總結

Node.js 透過幾個步驟就可以完成 Http Server 專案,和 Delphi WebBroker 專案相同,能夠在彈指之間建立專案,並且建立了 "/sum" 路由 (在 Delphi 中被稱為 action)。實際建構後你會發現程式碼全集中在 http.createServer 函式中,當專案需求功能越來越多,此函式會越來越難以維護。

下一篇文章會介紹 Express 套件如何來幫助我們完成原來的工作。


使用 Express 套件來升級 Http 服務為 RESTful API 專案

在建立 Node.js HTTP 伺服器的過程中,我們通常會面臨隨著專案成長,程式碼集中在 http.createServer 函式中,難以維護的情況。為了更有效地處理路由和中介軟體 (Middleware),我們可以引入 Express 框架。

Express 是一個快速、靈活且精簡的 Node.js Web 應用程式框架,它提供了一組強大的功能,讓你可以更輕鬆地組織和延伸你的應用程式。以下是如何使用 Express 來改進你的程式碼:

首先,你需要安裝 Express 套件。在 Terminal 中執行以下指令:

npm install express

接著 npm 就會安裝 express 套件,並把它安裝在 node_modules 中。

網路上很著名的 node_modules 迷因圖


此時專案資料夾結構應如下圖所示。




 

接著把 server.js 裡的程式碼以下面的程式碼替代。

const express = require('express');
const app = express();

// 引入 calc 模組
const calc = require('./app/calc');

// 設定 "/sum" 路由
app.get('/sum', (req, res) => {
  // 取得 URL 參數
  const { a, b } = req.query;

  // 將字串轉為數字
  const numA = parseInt(a, 10);
  const numB = parseInt(b, 10);

  // 使用 calc 模組計算結果
  const result = calc.add(numA, numB);

  // 回傳結果
  res.json({ result });
});

// 加上 root 路由

app.get('/', (req, res) => {
    res.end('Hello, World!\n');
});

// 啟動伺服器
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}/`);
});


這段程式碼使用 Express 框架建立一個簡單的 HTTP 伺服器。以下是程式碼的主要部分的解釋:

1. 引入 Express 框架:

這裡引入了 Express 框架並創建一個應用程式實例。

const express = require('express');
const app = express();


2. 引入 calc 模組:

 引入了 calc 模組,該模組包含一個 add 函數,用於執行兩數相加的操作。

 const calc = require('./app/calc');


3. 設定 "/sum" 路由:

這個路由處理函數處理 GET 請求,接收 /sum 路由中的 URL 參數 a 和 b,然後使用 calc 模組的 add 函數計算結果,最後以 JSON 格式回傳結果。

app.get('/sum', (req, res) => {
  // 處理 "/sum" 路由的 GET 請求
  const { a, b } = req.query; // 從 URL 參數中取得 a 和 b

  // 將字串轉為數字
  const numA = parseInt(a, 10);
  const numB = parseInt(b, 10);

  // 使用 calc 模組計算結果
  const result = calc.add(numA, numB);

  // 回傳結果
  res.json({ result });
});


4. 設定 "/" 路由:

這個路由就是還原根路徑的 GET 請求,回傳 Hello World 文字訊息。

app.get('/', (req, res) => {
    res.end('Hello, World!\n');
});


5. 啟動伺服器:

啟動伺服器,使其監聽在本地端口 3000 上,並在伺服器啟動時輸出一條訊息到 Terminal 中。

const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}/`);
});



使用 Express 套件來升級 Http 服務為 RESTful API 專案總結

使用 Express 框架的優點在於它提供了一個強大而靈活的 RESTful API 開發環境,我們可以在短時間內完成 Delphi WebBroker 和 DataSnap REST 框架所整合的效果。以下是我個人的總結:

    中介軟體的優勢: Express 提供了一個稱為中介軟體(Middleware)的概念,這是一個處理 HTTP 請求和回應的功能強大機制。這使我們能夠在請求到達路由處理之前或之後,執行額外的操作。例如,身份驗證、日誌記錄和錯誤處理等功能都可以方便地透過中介軟體實現。

    簡化的路由系統: Express 的路由系統相當簡單而直觀,對於建立 RESTful API 和處理複雜的路由配置都提供了極大的方便。這使得整合各種端點和資源變得輕鬆,並且易於擴展。

    簡潔的程式碼風格: Express 的 API 設計簡潔,使得開發者能夠以一種清晰且易讀的方式組織和編寫程式碼。這種風格的程式碼結構使得專案的維護和擴充更加輕鬆。

    豐富的社群技術支援: Express 是一個廣泛應用的框架,除了擁有龐大的社群和豐富的官方文件外,Stack Overflow 更有許多大神和無數追隨者的經驗傳承。這保證了開發者可以輕鬆找到解決問題的方法,並能夠分享最佳實戰之路。

    快速整合的效果: 使用 Express 能夠讓開發者迅速構建出符合需求的後端服務。這種快速整合的效果特別迎合 Delphi WebBroker 和 DataSnap REST 框架轉換的要求,讓原 Delphi 開發者在業務需求變動時更容易應對。

Express 提供了一個優雅的開發環境,對於中介軟體、簡潔的路由系統和整合效果的需求都提供了令人滿意的解決方案。在未來的後端開發中,這種風格的開發方式將有助於保持程式碼的清晰度,提升延伸的可能性,並帶來更高效的開發流程。這種轉變同時也能夠讓開發者更容易維護並有效地應對專案的需求變化。


和你分享。


See also

文首圖片來源:攝影師:Klaus Nielsen: https://www.pexels.com/zh-tw/photo/6287465/

 

 

 

2023/12/07

Visual Studio Code 延伸模組推薦

作者:吳祐賓





Visual Studio Code 是開發 Web 前後端很好用的文字編輯器,搭配上許多好用的延伸模組,可以節省很多輸入程式碼的時間。以下是我目前整理後還在使用的延伸模組:



1. Prettier

Prettier 是一個程式碼格式化工具,支援多種語言,確保你的程式碼風格一致,提升可讀性。


2. Todo Highlight

Todo Highlight 用於在程式碼中突顯顯示 TODO、FIXME 等註解,幫助你快速定位和處理待辦事項。


3. Chinese (Traditional) Language Pack for Visual Studio Code

Chinese (Traditional) Language Pack 將 Visual Studio Code 介面繁體中文化,提供更友善的使用體驗。

4. Auto Close Tag

Auto Close Tag 在輸入 HTML/XML 標籤時自動閉合標籤,提高撰寫效率,減少錯誤。


5. Auto Import

Auto Import 自動導入所需的模組或類別,減少手動引入的繁瑣步驟。

6. Auto Rename Tag

Auto Rename Tag 在修改 HTML/XML 標籤名稱時,自動修改對應的閉合標籤,保持標籤一致性。


7. ErrorLens

ErrorLens 透過直白的方式展示程式碼中的錯誤和警告,提高程式碼品質和可讀性。


8. ES6 String HTML

ES6 String HTML 提供對 ES6 模板字串中 HTML 的高亮和語法支援。


9. ES6 String JSX

ES6 String JSX 類似於 ES6 String HTML,但專注於 JSX 語法的高亮和支援。


10. Path Intellisense

Path Intellisense 自動提示檔案路徑,減少手動輸入和查找檔案的時間。


11. Debugger for Firefox

Debugger for Firefox 用於在 Visual Studio Code 中偵錯 Firefox 瀏覽器中的 JavaScript 程式碼。

12. ESLint

ESLint 整合 ESLint,用於靜態程式碼分析和檢測 JavaScript/TypeScript 程式碼中的潛在問題。

希望這些延伸模組能夠提升你在 Visual Studio Code 中的開發體驗!和你分享。



See also

文首圖片來源:攝影師:Karolina Grabowska: https://www.pexels.com/zh-tw/photo/usb-5882581/

2023/12/06

Node.js 入門

作者:吳祐賓




 

我們的目標是使用 Node.js 建立專屬於自己的 Web 應用程式 (Web Application)。在這第一個 Node.js 教學中,您將了解 Node 是什麼、如何在電腦上安裝它以及如何開始使用它。因此在接下來的教學中我們可以進行實際開發。讓我們開始吧!

Node.js 是什麼

  • Node.js 是開源、跨平台的 JavaScript 執行環境
  • Node.js 的授權方式為 MIT 授權,用於開發伺服器端 (後端) 和網路應用程式 (前端)
  • Node.js 是基於 Chrome V8 JavaScript 引擎來執行 JavaScript 程式碼
  • Node.js 使用事件驅動的非阻塞 I/O 模型,使其輕量且有效率
  • Node.js 使用 libuv 函式庫,這是一個專注於非同步 I/O 的多平台支援函式庫


Node.js 可執行 JavaScript 程式碼,JavaScript 屬於單執行緒程式語言,然而透過 libuv 函式庫讓它具備多執行緒的處理能力。在絕大多數的情況下我們並不會接觸到 libuv 這類底層。

libuv 官方 LOGO




為什麼要使用 Node.js

  • Node.js 讓開發人員能夠在前端和後端都使用 JavaScript。每個開發人員都可以了解專案裡的程式碼,並在必要時進行更改
  • Node.js 開發高吞吐量伺服器端應用程式經過許多大公司驗證使用它不會出太多怪手
  • Node.js 採取 MIT 授權,並可以完美運作在各大平台上,因此它可以幫助您節省基礎設施成本
  • Node.js 在 StackOverflow 上較容易取得各大高手的解決方案


安裝 Node.js

Windows: Node.js 官網下載 LTS (Long-term support 長期支援) 版本安裝即可

Linux (本文使用 Lubuntu 環境) 使用下列指令安裝:

# 安裝 Node.js
sudo apt-get install nodejs
# 安裝 NPM (Node Package Manager,是 Node.js 的套件(package)管理工具)
sudo apt-get install npm


安裝後先確認 Node.js 版本:

# 確認版本
node -v
npm -v






使用 Node.js 建立第一個 Hello World 程式

在建立專案前,我們可以在命令提示字元 (Terminal) 下體驗 JavaScript 開發,就像在 Browser 下測試 JavaScript 一樣。使用以下命令啟動 Node.js:

$ node
Welcome to Node.js v12.22.9.
Type ".help" for more information.
>

在 > 後面輸入 "console.log('Hello World')",就可以看到我們第一支 Hello World 程式執行的結果了!


這裡作為 Node.js 執行程式展示,還不會寫入任何檔案。


建立 index.js

在系統建立一個目錄,並使用任何一款的編輯軟體在該目錄建立 index.js,並把上一步驟的程式碼貼上去,如下圖:


接下來在 Terminal 裡輸入 "node index.js",即可看到執行結果。




接下來呢?

接下來我們會開始建立我們第一支 Web API 應用程式。敬請期待!

 

和你分享。

 

 

See also


2023/12/02

Ubuntu install Traditional Chinese input Chewing and Cangjie

作者:吳祐賓



 

Ubuntu 安裝 Taiwan 新酷音和倉頡。

因為網路上安裝步驟很零碎,所以記錄在這裡。



安裝 Fcitx5 新酷音 (注音 chewing)

有注音才能夠在 Terminal 進入"下載"資料夾

# 安裝新酷音注音輸入法
sudo apt install fcitx5 fcitx5-chewing fcitx5-chinese-addons
重新開機後即會看到鍵盤圖示在桌面右下角出現,右鍵選單會有新酷音。在設定畫面裡可以看到 Fcitx5 也安裝其它的輸入法。如下圖所示。





 

 

安裝 Fcitx5 倉頡、嘸蝦米等 (fcitx5-table-extra)

前一步驟安裝好 Fcitx5 後可以在簡體中文(中國)裡看到倉頡,它可以使用沒有問題。若你想使用繁體中文(台灣),我們繼續看下去。

繁體中文的 Fcitx5 倉頡確實存在,但它是透過 fcitx5-table-extra 套件提供的。但這個套件還在 Debian FTP Masters 審核。這裡就改使用 pkgs.org 提供編譯好的檔案。

這裡下載 Arch Linux Extra aarch64 (結稿時的版本為:fcitx5-table-extra-5.1.0-1-any.pkg.tar.xz)。下載後解壓縮,如下圖所示。


解壓縮後使用 Terminal 將目錄裡的資料複製到 /usr/share 目錄裡。可以使用以下指令:

sudo cp -r usr/share /usr/
# or
sudo cp -r usr/share/* /usr/share/


複製完成後,重新開機,接著就可以在 fcitx5 控制台裡看到繁體中文(台灣)區塊中看到增加的輸入法,如倉頡第五代、嘸蝦米等。如下圖所示。


現在可以享受新增的輸入法囉!



和你分享。


VMWare Tools install

sudo apt-get update
sudo apt-get install open-vm-tools open-vm-tools-desktop

How to share folder between host and VM

建立分享目錄,如下圖所示:

使用 "vmware-hgfsclient" 指令確認分享目錄是否出現。

將所有分享目錄掛載指令:

sudo vmhgfs-fuse -o allow_other .host:/ /mnt/hgfs

只是每次開機都要做這個動作,還在想這個問題要怎麼解決,目前就先建立捷徑在桌面上使用。


Ubuntu-sharing Mounting and Auto Mounting

網友 @darrenpmeyer https://gist.github.com/darrenpmeyer/b69242a45197901f17bfe06e78f4dee3 這篇文章寫得太完美,照著他的步驟做就可以完成一切,這裡把關鍵的 Mounting 和 Auto-Mounting 的內容照原文貼上,以免原文搬走後找不到的情況。

Mounting

To mount the filesystem, run:

sudo mount -t fuse.vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other

The shared folders will now be in subdirectories of /mnt/hgfs
Setting up auto-mounting


Add the following line to /etc/fstab:

.host:/    /mnt/hgfs    fuse.vmhgfs-fuse    auto,allow_other    0    0





See also

 

2023/12/01

Lazarus ZeosLib 7.2 轉換 Delphi 專案初體驗

作者:吳祐賓



Lazarus 發展到現在也很長的一段時間,雖然進度很慢,但 Lazarus 確實是存活著。作為 Delphi 7 替代品,也許它 -- Lazarus Free Pascal IDE 已經具備足夠的實力。

很奇怪的是,Lazarus 連結 MSSQL (SQL SERVER) 的資料是又少又零碎,和現在持續使用 Lazarus 的朋友請教後得到其連結法是:

  1. 使用 TMSSQLConnection 和 TSQLConnector 可以連結 MSSQL
  2. 必須搭配 TSQLTransaction 才能將異動資料寫回資料庫
  3. 需要有 DBLib 驅動程式 (32bit, 64bit) 才能連結資料庫

dbExpress 佈署到客戶端的即視感又回來了,這熟悉的感覺有點不妙。

記得 KTOP 蕭沖大俠曾經提過與其使用 Delphi 官方資料庫元件,不如直接採用 ZeosLib 這種開源專案會來得高效穩定。有想法,就來實際驗證看看。


什麼是 ZeosLib

ZeosLib 是一組資料庫元件,適用於MySQL、MariaDB、PostgreSQL、Interbase、Firebird、MS SQL Server、SAP Adaptive Server Enterprise 和Adaptive Server Anywhere(以前稱為Sybase)、Oracle 和SQLite for Delphi、FreePascal/Lazarus 和C++ Builder 。
--翻譯自 ZeosLib 官網
ZeosLib 也被稱為 ZeosDBO,現在穩定版本為 zeosdbo-7.2.14 版。ZeosLib 7.3 已改名版本為 8.x 版,8 多了 Transcation 元件,而且支援 OleDB 連線方式 (Windows 平台限定),只是目前仍在內部實驗中,建議使用 7.2.14 版本。元件如下表所示。

 




ZeosLib 連結 MSSQL 方式

首先,TZConnection.Protocol 設為 "ado",接著設定 TZConnection.Database 屬性,但設計模式下不會開啟 ConnectionString Builder Dialog (ZeosLib 8 開始加入),所以必須自己研究 ConnectionString 組合方式,這個網站有詳細的說明。如下圖所示。


其它的操作方式就和 Delphi 7 ADO 元件完全相同,使用 Lazarus 內建的 "Delphi Conversion",並將 ADO Type 指定以 ZeosLib Type 替換,之後就自動完成。

拿個小專案來轉換,使用者也沒感覺到太大的問題。


總結

雖然 Lazarus 的進展緩慢,但它確實存活並發展著。作為 Delphi 7 的替代品,Lazarus 在持續努力中展現出了足夠的實力。

在連結 MSSQL 資料庫方面,我理解到使用 TMSSQLConnection 和 TSQLConnector 可以成功連結 MSSQL,同時需要 TSQLTransaction 來確保異動資料能夠順利寫回資料庫。此外,安裝 32bit 和 64bit 的 DBLib 驅動程式是不可或缺的一步。

相較於 dbExpress 帶來的客戶端即視感,KTOP 蕭沖大俠的建議是采用 ZeosLib,這也讓我感到好奇。ZeosLib,或稱 ZeosDBO,是一組跨平台、跨開發工具的資料庫元件,支援多種資料庫,包括 MySQL、PostgreSQL、MS SQL Server 等。穩定版本 zeosdbo-7.2.14 已經在開發者中廣泛使用,而 ZeosLib 8.x 版本則帶來了更多新特性,例如 Transcation 元件和支援 OleDB 連線方式(僅限於 Windows 平台)。

在實際驗證中,我發現將 TZConnection 的 Protocol 設為 "ado",然後手動設定 TZConnection 的 Database 屬性,可以成功連結 MSSQL。儘管在設計模式下無法使用 ConnectionString Builder Dialog(ZeosLib 8 加入的新功能),但通過研究 ConnectionString 的組合方式,我能夠順利設定連線。

最後,透過 Lazarus 內建的 "Delphi Conversion" 工具,將 ADO 元件轉換為 ZeosLib Type,轉換小專案的過程相對順利,使用者幾乎感受不到太大的問題。

綜合而言,我見證了 Lazarus 的堅持與發展,還深入研究了 ZeosLib 作為一個強大的資料庫元件的表現。這樣的探索與實作,讓我更深刻地了解了 Lazarus 的價值與潛力。

和你分享


See also