Stack Stock Books に追加された参照系のAPIを試してみた

Stack Stock Books に参照系のAPIが追加されています。Wikiにはリファレンスが公開されてますが、具体例がまだ掲載されていないようですので、rubyからどのように使えるか試してみたいと思います。

追加されたのは、大きく以下の4つです。

  • 書籍情報
  • 利用者一覧
  • 利用者情報
  • 利用者蔵書一覧

rubyjsonを扱うためのライブラリはいくつか存在するみたいですが、ここではiStacでも使ったその名もズバリな'json'を使います。RubyGemsがインストールされている環境なら

gem install json

でインストールできると思います。
手作業でインストールする場合は以下からダウンロードしてきたらいいと思います。

書籍情報の取得

まず最初に書籍情報の取得を試してみます。
手っ取り早くirbを使って試してみます。

Macintosh:SSB snaka$ irb -Ku

irb(main):002:0> require 'net/http'
=> true
irb(main):003:0> require 'rubygems'
=> true
irb(main):004:0> require 'json'
=> true

irb(main):006:0> ssb = Net::HTTP.start('stack.nayutaya.jp')
=> #<Net::HTTP stack.nayutaya.jp:80 open=true>
irb(main):007:0> res = ssb.get('/api/book/id/364.json')
=> #<Net::HTTPOK 200 OK readbody=true>

irb(main):009:0> parsed = JSON.parse(res.body)
=> {"response"=>{"book"=>{"isbn10"=>"4274066371", ... (省略) }

# 本のタイトルを取得してみる
irb(main):010:0> parsed['response']['book']['title']
=> "On Lisp&#8212;Advanced Techniques for Common Lisp"

# 出版社を取得してみる
irb(main):011:0> parsed['response']['book']['publisher']
=> "オーム社"

# メッセージ
irb(main):012:0> parsed['message']
=> "処理されました。"

# 処理結果
irb(main):013:0> parsed['success']
=> true

irb(main):013:0> ssb.finish

なんか結果の確認の順番が逆のような気がしますが気にしないでください。
ちなみにレスポンスの中身は以下のような内容でした*1

irb(main):014:0> pp parsed
{"response"=>
  {"book"=>
    {"isbn10"=>"4274066371",
     "uri"=>"http://stack.nayutaya.jp/book/4274066371",
     "title"=>"On Lisp&#8212;Advanced Techniques for Common Lisp",
     "isbn13"=>"9784274066375",
     "publisher"=>"オーム社",
     "binding"=>"単行本",
     "book_id"=>364,
     "release_date"=>"2007-03-01",
     "image_uri"=>
      "http://ecx.images-amazon.com/images/I/41Vx%2BOomN3L._SL100_.jpg"}},
 "request"=>
  {"uri"=>"http://stack.nayutaya.jp/api/book/id/364.json",
   "include_authors"=>false},
 "version"=>"1.00",
 "success"=>true,
 "message"=>"処理されました。"}

titleで書名がimage_uriから書影のURIが取れるので、iStacに「登録する前に登録内容確認する」機能が実装できそうです。

実はiStacで今一番欲しかったのはこのAPIでした。iStacの今のバージョンでは残念ながら誤認識することが結構あって、それと気づかずに蔵書として登録されてしまうことが多々ありました。で、登録する前に一度その情報を確認してから... という機能を実装したかったんですが、以前のAPIではできなかったので今回のAPI追加は朗報でした。(認識精度を上げりゃいいって話でもありますが...)

上記の例では書籍idを使用してますが、ISBN10(ASIN)*2やISBN13でも書籍情報の取得ができるらしいです。詳細は、Stack Stock Books の Wikiを参照してください。

利用者一覧の取得

利用者の一覧が取得できます。
先ほどのirbの流れで確認してみます。以下のような感じで情報が取得できます。

irb(main):021:0> ssb.start
irb(main):021:0> ssb.get('/api/users.json')
=> #<Net::HTTPOK 200 OK readbody=true>
irb(main):022:0> res = ssb.get('/api/users.json')
=> #<Net::HTTPOK 200 OK readbody=true>
irb(main):023:0> parsed = JSON.parse(res.body)
=> {"response"=>{"users"=>[{"name"=>"xxxxxx", "uri"=> ...(省略)

# 処理結果
irb(main):025:0> parsed['success']
=> true

# メッセージ
irb(main):026:0> parsed['message']
=> "処理されました。"

# 1番目のユーザについての情報を取得してみる
# ユーザ名
irb(main):028:0> parsed['response']['users'][0]['name']
=> "hogehoge"
# ユーザページのURI
irb(main):029:0> parsed['response']['users'][0]['uri']
=> "http://stack.nayutaya.jp/user/hogehoge"
# アイコン画像のURI
irb(main):031:0> parsed['response']['users'][0]['icon_uri']
=> "http://stack.nayutaya.jp/user/hogehoge/icon.jpg"

irb(main):031:0> ssb.finish

返ってくるレスポンスは以下のような形式でした

{"response"=>
  {"users"=>
    [{"name"=>"hogehoge",
      "uri"=>"http://stack.nayutaya.jp/user/hogehoge",
      "nick"=>"hogehoge",
      "user_id"=>0000,
      "icon_uri"=>"http://stack.nayutaya.jp/user/hogehoge/icon.jpg"},
        :
       (省略)
        :
  }
 "request"=>
  {"uri"=>"http://stack.nayutaya.jp/api/users.json",
   "order"=>"user_id_desc",
   "page"=>1},
 "pagination"=>
  {"has_next_page"=>true,
   "total_entries"=>1223,
   "total_pages"=>13,
   "entries_per_page"=>100,
   "has_previous_page"=>false,
   "current_page"=>1},
 "version"=>"1.00",
 "success"=>true,
 "message"=>"処理されました。"
}

ユーザ個別の情報以外にも、paginationの中を見ると、全ユーザ数が1223であることが分かります。また、entries_par_pageから1ページ当りのユーザ数が100で、total_pagesから全13ページ、current_pageから現在は1ページの情報を取得していることが分かります。

利用者情報の取得

特定の利用者に関する情報が取得できるようです。

irb(main):041:0> ssb.start
irb(main):041:0> res = ssb.get('/api/user/name/snaka_ssb.json')
=> #<Net::HTTPOK 200 OK readbody=true>
irb(main):042:0> parsed = JSON.parse(res.body)
=> {"response"=>{"user"=>{"name"=>"snaka_ssb", "uri"=>"http://...." (省略)
# 取得できる内容は利用者一覧と同じなので省略
irb(main):042:0> ssb.finish

レスポンスは以下のような感じ

{"response"=>
  {"user"=>
    {"name"=>"snaka_ssb",
     "uri"=>"http://stack.nayutaya.jp/user/snaka_ssb",
     "nick"=>"snaka_ssb",
     "user_id"=>1137,
     "icon_uri"=>"http://stack.nayutaya.jp/user/snaka_ssb/icon.jpg"}},
 "request"=>{"uri"=>"http://stack.nayutaya.jp/api/user/name/snaka_ssb.json"},
 "version"=>"1.00",
 "success"=>true,
 "message"=>"処理されました。"
}

上記の例では利用者名を使用していますが、利用者名id1137 という感じで数値で表されるid">*3を使うこともできるようです。詳細は、Stack Stock BooksWikiを参照してください。

利用者の蔵書一覧の取得

最後に蔵書一覧についてみてみます。

irb(main):054:0> ssb.start
irb(main):054:0> res = ssb.get('/api/user/id/1137/stocks.json')
=> #<Net::HTTPOK 200 OK readbody=true>
irb(main):055:0> parsed = JSON.parse(res.body)

## 蔵書の数を調べてみる
irb(main):057:0> parsed['pagination']['total_entries']
=> 52

## 1番目の蔵書の情報を表示してみる
#  書名
irb(main):061:0> parsed['response']['stocks'][0]['book']['title']
=> "プログラミング言語C ANSI規格準拠"

#  著者の数
irb(main):062:0> parsed['response']['stocks'][0]['book']['authors'].size
=> 3

#  各著者の名前と役割
irb(main):063:0> parsed['response']['stocks'][0]['book']['authors'][0]
=> {"name"=>"B.W. カーニハン", "role"=>"", "author_id"=>430}
irb(main):064:0> parsed['response']['stocks'][0]['book']['authors'][1]
=> {"name"=>"D.M. リッチー", "role"=>"", "author_id"=>431}
irb(main):065:0> parsed['response']['stocks'][0]['book']['authors'][2]
=> {"name"=>"石田 晴久", "role"=>"翻訳", "author_id"=>432}

irb(main):065:0> ssb.finish

レスポンスは以下のような形式で返ってきます

{"response"=>
  {"stocks"=>
    [{"public"=>true,
      "date"=>"2008-10-19",
      "user_id"=>1137,
      "book_id"=>481,
      "stock_id"=>104134,
      "book"=>
       {"isbn10"=>"4320026926",
        "uri"=>"http://stack.nayutaya.jp/book/4320026926",
        "title"=>"プログラミング言語C ANSI規格準拠",
        "isbn13"=>"9784320026926",
        "publisher"=>"共立出版",
        "binding"=>"単行本",
        "release_date"=>"1989-06-01",
        "book_id"=>481,
        "authors"=>
         [{"name"=>"B.W. カーニハン", "role"=>"", "author_id"=>430},
          {"name"=>"D.M. リッチー", "role"=>"", "author_id"=>431},
          {"name"=>"石田 晴久", "role"=>"翻訳", "author_id"=>432}],
        "image_uri"=>
         "http://ecx.images-amazon.com/images/I/41W69WGATNL._SL100_.jpg"},
      "histories"=>[{"date"=>"2008-10-19", "state"=>"unread"}],
      "state"=>"unread"},
       :
      (省略)
       :
   "user"=>
    {"name"=>"snaka_ssb",
     "uri"=>"http://stack.nayutaya.jp/user/snaka_ssb",
     "nick"=>"snaka_ssb",
     "user_id"=>1137,
     "icon_uri"=>"http://stack.nayutaya.jp/user/snaka_ssb/icon.jpg"}},
 "request"=>
  {"uri"=>"http://stack.nayutaya.jp/api/user/id/1137/stocks.json",
   "order"=>"stock_updated_desc",
   "page"=>1},
 "pagination"=>
  {"has_next_page"=>false,
   "total_entries"=>52,
   "total_pages"=>1,
   "entries_per_page"=>100,
   "has_previous_page"=>false,
   "current_page"=>1},
 "version"=>"1.00",
 "success"=>true,
 "message"=>"処理されました。"
}

おおまかですが、今回追加された参照系APIは以上です。
最後に、Stack Stock Book の wiki へのリンクを掲載しておきます。ここでは取り上げなかったパラメタ等もあるので詳細は以下の wiki ページを参照してください。

なゆラボ

追記:2008.10.20

上記の実行例でHTTP#startとHTTP#finishは省略していたけど、やっぱり書いてた方が分かりやすそうなので追加しておいた。

*1:レスポンスはJSON形式で返ってきますこの例ではJSONをパースした結果のrubyオブジェクトをppで出力したものです

*2:厳密にはISBN10とASINは異なるものらしいですが...

*3:"user_id"=>1137 という感じで数値で表されるid