superagentのjsonpプラグインをnpmで作った
何か書いてみたいけど書くことがなかったのでしばらく前に作ったsuperagentのjsonpプラグインを作った話をしてみたいと思います。
先に作ったものを貼っておきます。
superagent
superagentはjavascriptのajaxライブラリでシンプルなメソッドチェインでajaxリクエストを送ることの出来るライブラリです。
SuperAgent - Ajax with less suck
request .post('/api/pet') .send({ name: 'Manny', species: 'cat' }) .set('X-API-Key', 'foobar') .set('Accept', 'application/json') .end(function(err, res){ if (res.ok) { alert('yay got ' + JSON.stringify(res.body)); } else { alert('Oh no! error ' + res.text); } });
なぜ作ったのか
superagentはajaxリクエストを送るライブラリなのでJSONPってそもそも?って感じですが、サーバに対するリクエストの書式を統一できるので(多分)多少メリットはあるのではないかなと思います。
superagentでjsonpを送ることの出来るnpmモジュールは既に別のものがありました。
しかし、「1. エラーハンドリングが出来ない、 2. superagentのplugin機構に則っていない *1、3. ただnpmモジュールを作ってみたかった」という理由から自分で作ってみることにしました。
実装
前項でも書きましたが、superagentにはplugin機構があります。 ちなみに、これはrequest変数を関数に渡してメソッドチェイン出来るようにしてくれているだけのものです。
Request.prototype.use = function(fn) { fn(this); return this; }
superagent-jsonpxもこのplugin機構に合うように作りました。
使い方としては以下のように使います。
var request = require('superagent'); var jsonp = require('superagent-jsonpx'); var options = { timeout: 3000, callbackKey: 'cb' }; request.get(uri) .use(jsonp(options)) .end(function (err, res) { if (!err && res.body) { // request success console.log(res.body); } else { // request timeout (or error) } });
jsonp
関数に options
を渡すとrequestを受け取る関数を返しています。
superagentで実際にajaxのリクエストが送られるのはendメソッドの中なのでプラグイン内でendメソッドをオーバーライドしてjsonpリクエストを送るようにしました。
ちなみにjsonpでは基本的にはエラーは取得出来ませんが、以下のページに書いてあったiframeを使う方法でエラーをハンドリングするようにしました。具体的にはiframeの特定の変数に値が一定時間経過後も入らなかった場合はエラーとして扱うようになっています。
npmモジュール周り
npmモジュールの作成に関しては以下の記事などわかりやすい記事がたくさんあったので全く困りませんでした。ありがとうございます。
その他、Travisやtestに使ったモジュールも初めてのものが多かったので書こうかと思いましたが大した内容でもないのに話が右往左往してしまいそうなのでこの辺で終了したいと思います。