React で使う HTTP クライアント候補として SuperAgent を試してみた

React と Redux には HTTP クライアントは含まれていない。 別途ライブラリを使う必要がある。 Web API を呼び出すためだけに jQuery を使うのはバカげているから、 専用のライブラリがいいね。

Browserify でビルドするから、npm にあるライブラリを使えるな。 ってことで、有名どころの SuperAgent を試してみる。

github.com

とはいえ、SuperAgent を試そうにも肝心の API サーバーが無いと話にならない。

まずは express をインストール。

npm install --save express

単純な API サーバーをこしらえてみた。

// server.js
var express = require("express");

// POST したデータをパースするために body-parser が別途必要
var bodyParser = require("body-parser");

var app = express();

// req.body をパースしてオブジェクトにするミドルウェアを使う
app.use(bodyParser.json());

var players = [
  { number: 10, name: "Kagawa" },
  { number: 4, name: "Honda" },
  { number: 5, name: "Nagatomo" },
  { number: 9, name: "Okazaki" }
];

app.get("/", function(req, res) {
  res.send("Hello Express");
});

app.get("/players", function(req, res) {
  res.send(players);
});

app.post("/players", function(req, res) {
  players.push({ 
    number: req.body.number,
    name: req.body.name
  });
  res.sendStatus(200);
});

app.get("/players/:number", function(req, res, next) {
  var targets = players.filter(function(p) {
    return p.number.toString() === req.params.number;
  });
  if (0 < targets.length) {
    res.send(targets[0]);
  } else {
    next();
  }
});

var server = app.listen(3000, function() {
  var host = server.address().address;
  var port = server.address().port;

  console.log("Listening at http://%s:%s", host, port);
});

express 初めて使ったけど、RubySinatra みたいに分かりやすい。 ・・・と思っていたよ。POST に対応するまでは。 POST したデータをパースするのに body-paraser が別途必要ってどうなのさ。 Sinatra みたいに params から取得できればいいのに。

気を取り直して、SuperAgent を試すとしよう。

npm でインストール。

npm install --save superagent

SuperAgent を使って、Web API を呼び出すコードを書く。

// client.js
var request = require("superagent");

request.get("http://localhost:3000/players")
  .end(function(err, res) {
    if (err) {
      console.log(err);
    } else {
      console.log(res.body);
    }
  });

request.post("http://localhost:3000/players")
  .send({ number: 7, name: "Shibasaki" })
  .end(function(err, res) {
    if (err) {
      console.log(err);
    } else {
      console.log(res.status);
    }
  });

request.get("http://localhost:3000/players/7")
  .end(function(err, res) {
    if (err) {
      console.log(err);
    } else {
      console.log(res.body);
    }
  });

先ほど作った API サーバーを起動し、

$ node server.js
Listening at http://:::3000

Web API を呼び出せることを確認。

$ node client.js
[ { number: 10, name: 'Kagawa' },
  { number: 4, name: 'Honda' },
  { number: 5, name: 'Nagatomo' },
  { number: 9, name: 'Okazaki' } ]
200
{ number: 7, name: 'Shibasaki' }

SuperAgent シンプルで悪くない。

メソッドチェインの形で POST するデータや追加のヘッダーを指定するインタフェースはちょっと変わってるな。 すぐ慣れたけど。 いや、end に渡すコールバックの第一引数がエラーなのにはまだ違和感残ってる。レスポンスが先であるべきじゃないかな。 Promise じゃないのもね・・・。

ただ、周辺ライブラリも揃っているのも魅力的。 Promise も、superagent-promise や superagent-bluebird-promise あたりを組み合わせる手があるにはあるか。