Nginx njs scripting, API服務的簡單實現

njs scripting 是什麼?

njs是JavaScript語言的子集,它允許擴展nginx功能。 njs的創建符合 ECMAScript 5.1 (嚴格模式)以及某些 ECMAScript 6 和更高版本的擴展。合規性還在不斷發展。 簡單說就是在nginx內使用JavaScript編寫簡單的服務端程序。

為什麼要選擇使用njs scripting

  • njs scripting的優點
  1. 使用js開發,開發簡單。便於快速開發
  2. 部署容易,有個nginx就可以,不需要部署其他東西,對server的性能要求很低, 也容易和其他服務共存。
  3. 在API層面可以保持穩定,以後轉成其他實現,也不會影響前端。

njs scripting適用於在項目初期需要一些服務端的功能,但是只希望有一個簡單實現,能快速開發部署,對其他發麵沒什麼要求。但是希望API保持穩定,不希望以後升級服務端的時候前端也要跟著改。

njs scripting 實例

通過一個簡單實例來體驗njs scripting。這個實例的api如下: http://xxx.xxx.xxx/fetch_data?offset=?&limit=? 從服務器獲取數據,offset是開始的位置,limit是一次獲取的數量, 在列表頁面或者瀑布流頁面常常需要類似的api進行展示。一般的實現是數據放在數據庫中,通過SQL獲取數據,然後發送給前端進行展示。一般需要一個應用服務器還有數據庫來做,這在有些項目中是沒必要的,開發部署都顯得過於復雜。

環境安裝配置

我是在ubuntu下安裝的, 直接用apt-get安裝

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Add the following line to /etc/apt/sources.list:
deb https://nginx.org/packages/ubuntu/ focal nginx
Install GPG key of the repository:

# wget https://nginx.org/keys/nginx_signing.key
# sudo apt-key add nginx_signing.key
Update the package index:
# sudo apt-get update
Install nginx-module-njs deb package:
# sudo apt-get install nginx-module-njs

nginx的配置文件如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
js_import /path/to/jsfile.js;   //你的JS文件的路徑
server {
    server_name xxxx.com;
    access_log /var/log/nginx/xxxx.com.access.log;
    error_log /var/log/nginx/xxxx.com.error.log info; //使用 info 級別 可以打出log,便於開發中的調試
    root /path/to/your/html;

    location /xxxxx {
        add_header  Content-Type 'application/json';
        js_content jsfile.your_func_name;
    }
}

JS文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function your_func_name(r) {
  var offset = 0; //default offset
  var limit = 20; //default limit

  // r.log('r.args.offset=' + r.args.offset);
  if(Number.isInteger(+r.args.offset)) {
    offset = parseInt(r.args.offset);
  }
  r.log('offset=' + offset);

  // r.log('r.args.limit=' + r.args.limit);
  if(Number.isInteger(+r.args.limit)) {
    limit = parseInt(r.args.limit);
  }
  r.log('limit=' + limit);

  var fs = require('fs').promises;
  fs.readFile("/path/data.json").
    then((data) => {
      var json = JSON.parse(data.toString());
      var output = [];
      for (var i = offset; (i < json.length) && (i < offset + limit); i++) {
        r.log('i=' + i);
        output.push(json[i]);
      }
      r.return(200, JSON.stringify(output));
    }).catch((error) => r.return(400, error));
}

export default { your_func_name };
  1. r.args中可以獲取request中的參數,比如r.args.offset可以獲取 request (http://xxx.com/api_name?offset=1) 中 offset參數的值
  2. r.log可以輸出log,log會輸出到 nginx中設置的文件中, 注意log級別. error_log /var/log/nginx/xxxx.com.error.log info; //使用 info 級別 可以打出log,便於開發中的調試
  3. r.return可以返回結果
  4. 實例中的數據保存在一個json文件中,api通過offset,limit輸出其中的一部分。
  5. 修改JS文件後,需要重啟nginx才會生效。

data.json

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    [
        {
            "a": "v1",
            "b": "v2",
            "c": "v3"
        },
        {
            "a": "v1",
            "b": "v2",
            "c": "v3"
        },
        {
            "a": "v1",
            "b": "v2",
            "c": "v3"
        }
    ]
记录并分享
Built with Hugo
Theme Stack designed by Jimmy