designetwork

ネットワークを軸としたIT技術メモ

Node.jsのHTTP通信はsync-request非推奨でthen-requestを推奨

f:id:daichi703n:20170221232447p:plain

こちらの記事で紹介しているとおり、sync-requestモジュールは同期処理でHTTP通信を行うことができる。これにより、javascript特有の非同期処理によるコールバック処理なく、シンプルなコードになる。

designetwork.hatenablog.com

designetwork.hatenablog.com

ところが、npmのsync-requestページで、商用では非推奨、then-requestへの切り替えを推奨されている。(2017/2/21確認)

npmのアナウンス

npmのsync-requestのページでは次の通りアナウンスされている。

www.npmjs.com

N.B. You should not be using this in a production application. In a node.js application you will find that you are completely unable to scale your server. In a client application you will find that sync-request causes the app to hang/freeze. Synchronous web requests are the number one cause of browser crashes. For production apps, you should use then-request, which is exactly the same except that it is asynchronous.

商用アプリケーションでのsync-requestの使用は非推奨。node.jsのアプリケーションがスケールしなくなる。sync-requestを使用することで、クライアントアプリがハングアップ・フリーズすることが分かる。同期処理でのWebリクエストはブラウザクラッシュの要因の一つだ。商用アプリでは、then-requestを使用すべきだ。それはsync-requestとほぼ同等だ。非同期であることを除いて。

非同期を避けて同期処理のsync-requestを使用しているので、その差分は受け入れられない。ただ、私の用途は開発環境なので、警告を受け入れて継続使用する。

sync-request Ver.4 で警告表示

使用開始当初はVer.3.0.1を使用。こちらのpackage.json(抜粋)で実行すると以下の結果となる。

"sync-request": "~3.x.x"

$ npm install
sync-request@3.0.1 node_modules/sync-request
├── http-response-object@1.1.0
└── concat-stream@1.6.0 (inherits@2.0.3, typedarray@0.0.6, readable-stream@2.2.2)

サンプルプログラムを実行
main

function https://google.comにアクセス(同期で完了待機)してStatus Codeを表示
↓return Status Code
main Status Codeを表示

$ node ./returnReqSync.js 
Start  Return Request Sync
Status Code (function) : 200
Status Code (main)     : 200
End    Return Request Sync

Version 4を使用してみる。

"sync-request": "~4.x.x"

$ npm install
sync-request@4.0.1 node_modules/sync-request
├── http-response-object@1.1.0
├── concat-stream@1.6.0 (inherits@2.0.3, typedarray@0.0.6, readable-stream@2.2.2)
└── get-port@2.1.0 (pinkie-promise@2.0.1)

実行すると、「Could not use “nc”, falling back to slower node.js method for sync requests.」の警告が表示される。npmの記載と同等内容だが、"nc"が何を指しているかは不明。エラーではないので無視する。

$ node ./returnReqSync.js 

Start  Return Request Sync
Could not use "nc", falling back to slower node.js method for sync requests.
Status Code (function) : 200
Status Code (main)     : 200
End    Return Request Sync

then-requestモジュールを使ってみる

せっかくなのでthen-requestモジュールに書き換えてみる。使い方はnpmを参照。

var request = require('then-request');
var returnCode;

console.log("Start  Return Request Sync");
returnCode = httpGet();
console.log("Status Code (main)     : "+returnCode);
console.log("End    Return Request Sync");

function httpGet(){
  //var response = request('GET', 'https://google.com/'); //pattern of sync-request
  request('GET', 'https://google.com/').done(function (response) {
    console.log("Status Code (function) : "+response.statusCode);
    return response.statusCode;
  });
}

実行するとこの通り、非同期処理となってmain関数の表示時点で値が返っていないことが分かる。

$ node ./returnReqThen.js 
Start  Return Request Sync
Status Code (main)     : undefined
End    Return Request Sync
Status Code (function) : 200

まとめ - Node.jsのHTTP処理はsync-request非推奨になりthen-requestを推奨

非推奨とは言え、現状でHTTP同期処理を簡単に実装できるsync-requestは非常に有用だ。私は開発環境用途なので引き続き使用していく。非同期で問題ない場合は、sync-requestの豊富なオプションを継承しているthen-requestへの切り替えを考慮しても良い。