Node.js向けHTTPクライアントGot
普段はクライアントサイドのJSも書くことがあるのでNode.jsではnode-fetch を使っているのですが、StreamAPIが使いたかったりクライアントの層でキャッシュしたくなっていい感じのHTTPクライアントないかなと思って探してみたらGot というライブラリを見つけたので試してみました。
特徴
詳細 はREADME参照ですがいくつかかいつまんでみるとこんな感じです。
- サイズが軽量でrequest の1/10程度
- PromiseとStreamAPI両方に対応
- RFC 7234に準拠したキャッシュ
- リダイレクトのフォロー
- リトライ
- HTTP2は実験的なサポート
- ブラウザには非対応
- 名前からお察しの通りググラビリティは壊滅的
- ライセンスはMIT
(
9.6.0
現在)
使い方
インストール
yarnかnpmでインストールするだけでOK。
$ yarn add got
以後のサンプルは9.6.0
のものです。
基本的な使い方
Promiseでレスポンスが返ってくる感じで説明不要なくらいシンプル。
const got = require('got');
(async () => {
try {
const response = await got('https://example.com');
console.log(response.body);
} catch (error) {
console.log(error.response.body);
}
})();
GET以外は用意されているメソッドを使う。
リクエストボディでJSONを投げる場合はオプションのjson
にtrue
を設定するとbody
に指定したオブジェクトをJSONに変換して投げてくれるが、json
がtrue
だとレスポンスボディもJSONじゃないとだめらしくレスポンスがプレーンテキストだったりすると死ぬので注意。
const response = await got.post('https://example.com', {
body: {
hello: 'world'
},
json: true,
});
console.log(response.body);
StreamAPI
stream
というメソッドを使うとPromiseではなくReadableStreamで返ってくる。
got.stream('https://example.com').pipe(writableStream);
ReadableStreamからリクエストを投げたい場合はstream
にpost
メソッドがあるのでpipe
する。
readableStream.pipe(got.stream.post('https://example.com'));
キャッシュ
レスポンスを自由にキャッシュできるわけではなくRFC 7234に準拠した形でキャッシュされる。
なのでレスポンスヘッダにexpires
やcache-control
とかがないと設定してもキャッシュされないっぽい。
一番シンプルな方法は適当なMap
オブジェクトを渡せばOK。
二回目のリクエストからはキャッシュがあればキャッシュを返すのでその場合は早い。
キャッシュが返った場合はレスポンスのfromCache
がtrue
になる。
const got = require('got');
const cache = new Map();
const url = 'https://octodex.github.com/images/original.png';
(async () => {
const first = await got(url, { cache });
console.log(first.fromCache); // false
const second = await got(url, { cache });
console.log(second.fromCache); // true
})();
Redisなど各種ストレージのアダプタが提供されているのでそれを使えばMap
以外に保存できる。
多分インターフェイス合わせれば自作も可能っぽい。
リトライ
設定したステータスコードの場合にリトライする機能。
400番台と500番台全部でリトライするわけではなくデフォルトだとワンチャンありそうなステータスコードの時のみリトライするようになっていてオプションで変更もできる。
リトライ回数だけを指定する場合はリトライ回数だけ指定すればOKで細かいオプションを指定する場合はオブジェクトで設定する。
リトライの間隔は1秒、2秒,4秒,8秒と増えていくタイプ。
const response = await got.get('https://example.com', {
retry: 3,
});
まとめ
軽量ですが機能はリッチな印象でした。
ドキュメントが量ある割にわかりにくいのとググラビリティが絶望的なのは残念ポイント。