シンプルに Web API を叩ける WebService::Simple の現在の最新版はヴァージョン 0.09 です。 ヴァージョン 0.03 からスーパーハカーによる修正が入ったこともあり、機能が(Simpleという名前を崩さない程度に)増えたり、多少インターフェースが変わったりしました。 そこで WebService::Simple 0.09 の使い方を POD より詳しめに解説します。 # shipit が便利だったので、調子に乗ってやたら使いまくったらヴァージョンがどんどんあがっちゃった><
最初に、インターフェースの変更点をあげます。大きく変わったのは一点のみです。 例えば、Lingr の API を扱う場合、base_url は http://www.lingr.com/ になりますが、 各メソッドの URL は 例えば http://www.lingr.com/api/session/create という風に、メソッドごとに変化します。つまり base_url に api/session/create みたいなパスを追加したいということです。 そのためには、 get メソッド の パラメータ にそのパスを記載するんですが、0.03 の時と引渡し方が変更になっています。 第1引数に extra_path を指定するようになりました。
my $lingr = WebService::Simple->new( base_url => 'http://www.lingr.com/', param => { api_key => "your_api_key", format => 'xml' } ); my $response = $lingr->get( 'api/session/create', {} ); my $session = $response->parse_response->{session};
また、上記サンプルに記載されているように、get などで取得した WebService::Simple::Response オブジェクトをパースするには、parse_xml メソッドを今まで呼んででいましたが、parse_response メソッドを使うことを推奨しています(エイリアスを作っているので parse_xml でも動きます)。
あとは普通に使う分には今まで通りで問題ないです。 Flickr API を使ったキーワードによる検索結果を Dump するサンプルコードは以下のようになります。
use strict; use warnings; use WebService::Simple; use Data::Dumper; my $flickr = WebService::Simple->new( base_url => "http://api.flickr.com/services/rest/", param => { api_key => "your_api_key", } ); my $response = $flickr->get( { method => "flickr.photos.search", text => "cat" } ); print Dumper $response->parse_response;
response のキャッシュも以前と同じ書き方でできます。
use WebService::Simple; use Cache::File; my $cache = Cache::File->new( cache_root => '/tmp/mycache', default_expires => '30 min', ); my $flickr = WebService::Simple->new( base_url => "http://api.flickr.com/services/rest/", cache => $cache, param => { api_key => "your_api_key", } );
次にこの WebService::Simple を継承したサブクラスを作って、もうちょっと楽に API を触れるという方法を紹介します。 例えば、Flickr API の flickr.test.echo 及び flickr.photos.search を呼び出す WebService::Simple::Flickr をこんな感じで作ります。
package WebService::Simple::Flickr; use base qw(WebService::Simple); __PACKAGE__->config( base_url => "http://api.flickr.com/services/rest/", ); sub test_echo { my ($self,$str) = @_; return $self->get( { method => "flickr.test.echo", name => $str } ); } sub photos_search { my ($self,$str) = @_; return $self->get( { method => "flickr.photos.search", text => $str } ); }
そしたら外部から、よりスッキリとしたコードで API をたたくことができます。
use utf8; use WebService::Simple::Flickr; use Data::Dumper; my $flickr = WebService::Simple::Flickr->new( param => { api_key => "your_api_key", } ); my $ref = $flickr->photos_search("富士山")->parse_response; print Dumper $ref;
この API ごとにサブクラス化するという方法なんですが、Yappo さんが作った WebService::Simple::Cabinet を使う方法と、「ある API に特化したモジュールもしくはメソッドを作る」という点で似ています。WebService::Simple::Cabinet は YAML 形式などで API の定義をしますが、この場合は Perl モジュールを作っています。API を使うシチュエーションによってどちらか選ぶというのもいいと思います。
最後にパーサー、つまりAPI から返却されたコンテンツをパースするのに使うモジュールが選べるようになったという機能を紹介します。デフォルトでは XML::Simple でパースするようになっていますが、例えば XML::LibXML を使いたい場合は、WebService::Simple::Parser を継承して WebService::Simple::Parser::XML::LibXML モジュールを以下のように作成します( このモジュールはWebService::Simple に同封されています)。
package WebService::Simple::Parser::XML::LibXML; use strict; use warnings; use base qw(WebService::Simple::Parser); use XML::LibXML; __PACKAGE__->mk_accessors($_) for qw(libxml); sub new { my $class = shift; my $args = shift || {}; $args->{libxml} ||= XML::LibXML->new; $class->SUPER::new($args); } sub parse_response { my $self = shift; $self->libxml->parse_string( $_[0]->content ); } 1;
それで利用するスクリプトからは、WebService::Simple のコンストラクタの引数 response_parser の値で使いたいパーサのモジュールを指定します。
my $service = WebService::Simple->new( base_url => "http://api.flickr.com/services/rest/", response_parser => 'XML::LibXML', params => { api_key => "your_api_key" } );
これで面白いのは、とりわけ XML で結果が返ってくる API 以外にも対応するところです。 例えば、JSON もしくは JSONP 形式で返却される API を扱うこともできます。 WebService::Simple::Parser::JSON はもう既に定義済みのものがあるので、以下のようなスクリプトを書くだけで、JSON もしくは JSONP を パースしてくれてデータを利用することができます。
use strict; use warnings; use WebService::Simple; use Data::Dumper; my $flickr = WebService::Simple->new( base_url => "http://api.flickr.com/services/rest/", response_parser => 'JSON', params => { api_key => "your_api_key", format => "json" } ); my $response = $flickr->get( { method => "flickr.photos.search", text => "cat" } ); print Dumper $response->parse_response;
あとは POST にも対応したので、使いたい場合は post メソッドを get と同じ引数形式で呼び出せばおkだと思います。
dmaki(lestrrat)さん、tokuhirom に(まるごと)書き換えてもらった&Yappo さんが WebService::Simple::Cabinet を作ったおかげで、面白いモジュールになった気がします。感謝です。
CPAN に最新版があがっているので、もしよろしければご利用ください。