Facebook の中核をなすのはソーシャルグラフですが、そのソーシャルグラフへ外部開発者がアクセスする手段として、Facebook Platform は Graph API を提供しています。この Graph API が提供する機能を利用すると、ユーザやその友だちの情報を取得したり、イベントやグループを作成したり、Facebook ページを管理するなど様々なことができます。ただし、情報の読み書きをするには頻繁に API を利用する必要があるため、安易に多用するとリクエストが増えてサービスのレスポンスが悪くなってしまったりします。
Facebook Platform はそれを解消するための機能をいくつか提供しているので、今回は、最近作り始めた Facebook::OpenGraph というモジュールを例にして、それらの手段を紹介します。
通常のアクセス
便利機能とは別ですが、Open Graph オブジェクトへの通常のアクセス方法です。curl -X GET \一般公開されたプロパティを取得するだけであれば、とくにアクセストークンの指定は必要ありません。
https://graph.facebook.com/4
Facebook::OpenGraphの場合だと以下のようになります。
my $fb = Facebook::OpenGraph->new;
my $user = $fb->fetch(4);
# 第2引数にパラメータ指定可。$fb->fetch(4, +{locale => 'ja_JP'})
返り値
$VAR1 = {
'link' => 'http://www.facebook.com/zuck',
'name' => 'Mark Zuckerberg',
'locale' => 'en_US',
'username' => 'zuck',
'last_name' => 'Zuckerberg',
'id' => '4',
'first_name' => 'Mark',
'gender' => 'male'
};
Batch Request
Batch Requestは複数のHTTPリクエストを1つにまとめる機能で、複数オブジェクトの情報を一気に取得するだけでなく、1つ1つのリクエストのHTTPメソッドを指定して読み書きを同時に扱うことも出来ます。curl -X POST \詳しくはBatch Requestドキュメントの和訳をご覧ください。
-F 'batch=[{"relative_url":"4","method":"GET"},{"relative_url":"44007581","method":"GET"}]' \
-F 'access_token=1234567|fooBarBuzz' \
https://graph.facebook.com
Facebook::GraphAPIだと以下のようにして複数オブジェクトを取得できます。
my $fb = Facebook::OpenGraph->new(+{app_id => 1234567, secret => 'app_secret_key'});
$fb->set_app_token;
my $users = $fb->bulk_fetch([qw/4 44007581/]);
返り値
$VAR1 = [また、batchメソッドを利用して個々のリクエスト内容を詳細に指定することも可能です。
{
'link' => 'http://www.facebook.com/zuck',
'name' => 'Mark Zuckerberg',
'locale' => 'en_US',
'username' => 'zuck',
'last_name' => 'Zuckerberg',
'id' => '4',
'first_name' => 'Mark',
'gender' => 'male'
},
{
'link' => 'http://www.facebook.com/go.hagiwara',
'name' => "\x{8429}\x{539f} \x{8c6a}",
'locale' => 'en_US',
'username' => 'go.hagiwara',
'id' => '44007581',
'first_name' => "\x{8c6a}",
'last_name' => "\x{8429}\x{539f}",
'gender' => 'male'
}
];
my $fb = Facebook::OpenGraph->new(+{access_token => '1234567|fooBarBuzz'});
my $responses = $fb->batch([
+{ # ユーザ自身の情報取得
method => 'GET',
relative_url => 'me?fields=picture'
},
+{ # ユーザのウォールに書き込み
method => 'POST',
relative_url => 'me/feed',
body => 'message=TEST&link=https://developers.facebook.com/'
},
]);
FQL
FQLを利用した情報取得は通常、以下の通りです。curl 'https://graph.facebook.com/fql?q=SELECT+display_name%2C+icon_url+FROM+application+WHERE+app_id+%3D+127497087322461'Facebook::OpenGraphだと以下の通りです。
my $fb = Facebook::OpenGraph->new;
my $res = $fb->fql(
'SELECT display_name, icon_url FROM application WHERE app_id = 127497087322461'
);
返り値
{
'data' => [
{
'icon_url' => 'http://photos-c.ak.fbcdn.net/photos-ak-snc7/v43/45/127497087322461/app_2_127497087322461_1287.gif',
'display_name' => 'app'
}
]
};
FQL Multi-query
bulk_fqlを用いると、複数のfqlクエリを一つにまとめることが出来ます。my $datam = $fb->bulk_fql(+{
"all friends" => "SELECT uid2 FROM friend WHERE uid1=me()",
"my name" => "SELECT name FROM user WHERE uid=me()",
})->{data};
返り値
[また、2つ以上のクエリの依存関係も扱うことができます。
+{
fql_result_set => [
+{
uid2 => '100004652133279',
},
+{
uid2 => '100004657083353'
},
],
name => 'all friends',
},
+{
fql_result_set => [
+{
name => 'Linda Amdgjheicghf Laustein',
},
],
name => 'my name',
},
];
my $datam = $fb->bulk_fql(+{
"query1" => "SELECT uid, rsvp_status FROM event_member WHERE eid=12345678
",
"query2" => "SELECT name, url, pic FROM profile WHERE id IN (SELECT uid FROM #query1)"
})->{data};
Fields Expansion
Fields Expansionは、これまでのfieldsパラメータの拡張を可能にするものです。以前であれば、/me?fields=picture のように fields パラメータを指定する場合、そこに指定できるのはオブジェクトのフィールドのみでした。この機能により、fieldsパラメータにオブジェクトのコネクションや、そのコネクションを構成するオブジェクトのコネクション、そしてそのコネクションを構成するオブジェクトの。。。という具合に入れ子にすることが可能になりました。curl -X GET \このように指定した場合、ユーザのname, emailフィールドの他に、albumsコネクションを通じてユーザが所有するアルバム5件のname、さらにそれぞれのアルバムのphotosコネクションを通じて、写真3枚のname, pictureフィールド、それから写真にタグ付けされているオブジェクト2件を返します。
https://graph.facebook.com/me\
?access_token=USER_ACCESS_TOKEN\
&fields=name,email,albums.fields(name,photos.fields(name,picture,tags.limit(2)).limit(3)).limit(5)
以下のような書き方が出来ます。
my $fb = Facebook::GraphAPI->new(+{access_token => '1234567|fooBarBuzz'});上記のように書いていると入れ子が分かりにくいという場合は、以下のように書くことも可能です。
$fb->fetch('me', +{
fields => 'name,email,albums.fields(nam.......',
});
$fb->fetch('me', +{user_basic_fields.yamlなどの外部ファイルを作っておくのも良いのかもしれません。というのも、通常は全件返されていたAPIが突然25件しか返さなくなったという不具合が夏にあったためです。こうして別ファイルに書いておくと、担当者でなくても把握しやすくなり、暫定的にlimit: 5000を足そうという解決策が見つけやすくなるかもしれません。
fields => [
'name',
'email',
+{
'albums' => +{
'fields' => [
'name',
+{
'photos' => +{
'fields' => [
'name',
'picture',
+{
'tags' => +{
'limit' => '2'
}
}
],
'limit' => '3'
}
}
],
'limit' => '5'
}
}
]
});
user_basic_fields.yaml
- name
- albums:
limit: 5
fields:
- name
- photos:
limit: 3
fields:
- name
- picture
- tags:
limit: 2
use YAML qw(LoadFile);
my $fb = Facebook::GraphAPI->new(+{access_token => '1234567|fooBarBuzz'});
my $fields = LoadFile('user_basic_fields.yaml');
my $user = $fb->fetch('me', +{fields => $fields});
返り値
以下の通り、fileds に指定した入れ子構造が維持された状態で返されます。
{
email => 'foo_bar_buzz@tfbnw.net',
name => 'Linda Amdgjheicghf Laustein',
id => '12345678',
albums => +{
data => [
+{
created_time => '2012-11-20T10:35:36+0000',
name => 'test album',
id => 111111111111111,
photos => +{
data => [
+{
created_time => '2012-11-20T10:35:41+0000',
name => 'abc',
id => 123456,
picture => 'http://photos-a.ak.fbcdn.net/hphotos-ak-ash4/123456_s.jpg',
tags => +{
paging => +{
next => 'https://graph.facebook.com/12345678/tags?limit=2&offset=2',
},
data => [
+{
y => '50.42735042735',
created_time => '2012-11-20T10:36:55+0000',
name => '100004657083353',
x => '74.137931034483'
},
+{
y => '33.333333333333',
created_time => '2012-11-20T10:36:37+0000',
name => '100004691462769',
x => '47.931034482759'
},
],
},
},
+{
created_time => '2012-11-20T10:35:41+0000',
name => 'def',
id => 23456,
picture => 'http://photos-h.ak.fbcdn.net/hphotos-ak-prn1/23456_s.jpg',
tags => +{
paging => +{
next => 'https://graph.facebook.com/12345678/tags?limit=2&offset=2'
},
data => [
+{
y => '37.142857142857',
created_time => '2012-11-20T10:36:50+0000',
name => '100004657083353',
x => '44.137931034483'
},
],
},
},
+{
created_time => '2012-11-20T10:35:41+0000',
id => 34567,
picture => 'http://photos-g.ak.fbcdn.net/hphotos-ak-ash3/34567_s.jpg'
},
],
},
},
],
}
};
ここでは Batch Reuqest, FQL Multi-query, Fields Expansion など、複数のリクエストをまとめて HTTP リクエスト数を減らす機能に絞って紹介しましたが、OpenGraph.pm の主要なメソッドの脇には、該当ドキュメントのURLがコメントで書かれていますので、まだ作成中ですが何かの役に立つかもしれません。